Chromium Code Reviews| 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 |