OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 3497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3508 __ JumpIfNotSmi(exponent, &exponent_not_smi); | 3508 __ JumpIfNotSmi(exponent, &exponent_not_smi); |
3509 __ SmiUntag(exponent); | 3509 __ SmiUntag(exponent); |
3510 __ jmp(&int_exponent); | 3510 __ jmp(&int_exponent); |
3511 | 3511 |
3512 __ bind(&exponent_not_smi); | 3512 __ bind(&exponent_not_smi); |
3513 __ vldr(double_exponent, | 3513 __ vldr(double_exponent, |
3514 FieldMemOperand(exponent, HeapNumber::kValueOffset)); | 3514 FieldMemOperand(exponent, HeapNumber::kValueOffset)); |
3515 } | 3515 } |
3516 | 3516 |
3517 if (exponent_type_ != INTEGER) { | 3517 if (exponent_type_ != INTEGER) { |
3518 Label int_exponent_convert; | |
3518 // Detect integer exponents stored as double. | 3519 // Detect integer exponents stored as double. |
3519 __ vcvt_u32_f64(single_scratch, double_exponent); | 3520 __ vcvt_u32_f64(single_scratch, double_exponent); |
3520 // We do not check for NaN or Infinity here because comparing numbers on | 3521 // We do not check for NaN or Infinity here because comparing numbers on |
3521 // ARM correctly distinguishes NaNs. We end up calling the built-in. | 3522 // ARM correctly distinguishes NaNs. We end up calling the built-in. |
3522 __ vcvt_f64_u32(double_scratch, single_scratch); | 3523 __ vcvt_f64_u32(double_scratch, single_scratch); |
3523 __ VFPCompareAndSetFlags(double_scratch, double_exponent); | 3524 __ VFPCompareAndSetFlags(double_scratch, double_exponent); |
3524 __ vmov(exponent, single_scratch, eq); | 3525 __ b(eq, &int_exponent_convert); |
Yang
2011/12/09 12:04:37
We try to detect integer values saved in the doubl
| |
3525 __ b(eq, &int_exponent); | |
3526 | 3526 |
3527 if (exponent_type_ == ON_STACK) { | 3527 if (exponent_type_ == ON_STACK) { |
3528 // Detect square root case. Crankshaft detects constant +/-0.5 at | 3528 // Detect square root case. Crankshaft detects constant +/-0.5 at |
3529 // compile time and uses DoMathPowHalf instead. We then skip this check | 3529 // compile time and uses DoMathPowHalf instead. We then skip this check |
3530 // for non-constant cases of +/-0.5 as these hardly occur. | 3530 // for non-constant cases of +/-0.5 as these hardly occur. |
3531 Label not_plus_half; | 3531 Label not_plus_half; |
3532 | 3532 |
3533 // Test for 0.5. | 3533 // Test for 0.5. |
3534 __ vmov(double_scratch, 0.5); | 3534 __ vmov(double_scratch, 0.5); |
3535 __ VFPCompareAndSetFlags(double_exponent, double_scratch); | 3535 __ VFPCompareAndSetFlags(double_exponent, double_scratch); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3572 AllowExternalCallThatCantCauseGC scope(masm); | 3572 AllowExternalCallThatCantCauseGC scope(masm); |
3573 __ PrepareCallCFunction(0, 2, scratch); | 3573 __ PrepareCallCFunction(0, 2, scratch); |
3574 __ SetCallCDoubleArguments(double_base, double_exponent); | 3574 __ SetCallCDoubleArguments(double_base, double_exponent); |
3575 __ CallCFunction( | 3575 __ CallCFunction( |
3576 ExternalReference::power_double_double_function(masm->isolate()), | 3576 ExternalReference::power_double_double_function(masm->isolate()), |
3577 0, 2); | 3577 0, 2); |
3578 } | 3578 } |
3579 __ pop(lr); | 3579 __ pop(lr); |
3580 __ GetCFunctionDoubleResult(double_result); | 3580 __ GetCFunctionDoubleResult(double_result); |
3581 __ jmp(&done); | 3581 __ jmp(&done); |
3582 | |
3583 __ bind(&int_exponent_convert); | |
3584 __ vcvt_u32_f64(single_scratch, double_exponent); | |
3585 __ vmov(exponent, single_scratch); | |
3582 } | 3586 } |
3583 | 3587 |
3584 // Calculate power with integer exponent. | 3588 // Calculate power with integer exponent. |
3585 __ bind(&int_exponent); | 3589 __ bind(&int_exponent); |
3586 | 3590 |
3587 __ mov(scratch, exponent); // Back up exponent. | 3591 __ mov(scratch, exponent); // Back up exponent. |
3588 __ vmov(double_scratch, double_base); // Back up base. | 3592 __ vmov(double_scratch, double_base); // Back up base. |
3589 __ vmov(double_result, 1.0); | 3593 __ vmov(double_result, 1.0); |
3590 | 3594 |
3591 // Get absolute value of exponent. | 3595 // Get absolute value of exponent. |
(...skipping 30 matching lines...) Expand all Loading... | |
3622 | 3626 |
3623 // The stub is called from non-optimized code, which expects the result | 3627 // The stub is called from non-optimized code, which expects the result |
3624 // as heap number in exponent. | 3628 // as heap number in exponent. |
3625 __ bind(&done); | 3629 __ bind(&done); |
3626 __ AllocateHeapNumber( | 3630 __ AllocateHeapNumber( |
3627 heapnumber, scratch, scratch2, heapnumbermap, &call_runtime); | 3631 heapnumber, scratch, scratch2, heapnumbermap, &call_runtime); |
3628 __ vstr(double_result, | 3632 __ vstr(double_result, |
3629 FieldMemOperand(heapnumber, HeapNumber::kValueOffset)); | 3633 FieldMemOperand(heapnumber, HeapNumber::kValueOffset)); |
3630 ASSERT(heapnumber.is(r0)); | 3634 ASSERT(heapnumber.is(r0)); |
3631 __ IncrementCounter(counters->math_pow(), 1, scratch, scratch2); | 3635 __ IncrementCounter(counters->math_pow(), 1, scratch, scratch2); |
3632 __ Ret(2 * kPointerSize); | 3636 __ Ret(2); |
Yang
2011/12/09 12:04:37
On ARM we don't multiply with kPointerSize.
| |
3633 } else { | 3637 } else { |
3634 __ push(lr); | 3638 __ push(lr); |
3635 { | 3639 { |
3636 AllowExternalCallThatCantCauseGC scope(masm); | 3640 AllowExternalCallThatCantCauseGC scope(masm); |
3637 __ PrepareCallCFunction(0, 2, scratch); | 3641 __ PrepareCallCFunction(0, 2, scratch); |
3638 __ SetCallCDoubleArguments(double_base, double_exponent); | 3642 __ SetCallCDoubleArguments(double_base, double_exponent); |
3639 __ CallCFunction( | 3643 __ CallCFunction( |
3640 ExternalReference::power_double_double_function(masm->isolate()), | 3644 ExternalReference::power_double_double_function(masm->isolate()), |
3641 0, 2); | 3645 0, 2); |
3642 } | 3646 } |
(...skipping 3714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7357 __ StoreNumberToDoubleElements(r0, r3, r1, r5, r6, r7, r9, r10, | 7361 __ StoreNumberToDoubleElements(r0, r3, r1, r5, r6, r7, r9, r10, |
7358 &slow_elements); | 7362 &slow_elements); |
7359 __ Ret(); | 7363 __ Ret(); |
7360 } | 7364 } |
7361 | 7365 |
7362 #undef __ | 7366 #undef __ |
7363 | 7367 |
7364 } } // namespace v8::internal | 7368 } } // namespace v8::internal |
7365 | 7369 |
7366 #endif // V8_TARGET_ARCH_ARM | 7370 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |