| 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 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 __ movq(rdx, FieldOperand(rax, String::kLengthOffset)); | 259 __ movq(rdx, FieldOperand(rax, String::kLengthOffset)); |
| 260 __ SmiTest(rdx); | 260 __ SmiTest(rdx); |
| 261 __ j(zero, &false_result); | 261 __ j(zero, &false_result); |
| 262 __ jmp(&true_result); | 262 __ jmp(&true_result); |
| 263 | 263 |
| 264 __ bind(¬_string); | 264 __ bind(¬_string); |
| 265 __ CompareRoot(rdx, Heap::kHeapNumberMapRootIndex); | 265 __ CompareRoot(rdx, Heap::kHeapNumberMapRootIndex); |
| 266 __ j(not_equal, &true_result); | 266 __ j(not_equal, &true_result); |
| 267 // HeapNumber => false iff +0, -0, or NaN. | 267 // HeapNumber => false iff +0, -0, or NaN. |
| 268 // These three cases set the zero flag when compared to zero using ucomisd. | 268 // These three cases set the zero flag when compared to zero using ucomisd. |
| 269 __ xorpd(xmm0, xmm0); | 269 __ xorps(xmm0, xmm0); |
| 270 __ ucomisd(xmm0, FieldOperand(rax, HeapNumber::kValueOffset)); | 270 __ ucomisd(xmm0, FieldOperand(rax, HeapNumber::kValueOffset)); |
| 271 __ j(zero, &false_result); | 271 __ j(zero, &false_result); |
| 272 // Fall through to |true_result|. | 272 // Fall through to |true_result|. |
| 273 | 273 |
| 274 // Return 1/0 for true/false in rax. | 274 // Return 1/0 for true/false in rax. |
| 275 __ bind(&true_result); | 275 __ bind(&true_result); |
| 276 __ Set(rax, 1); | 276 __ Set(rax, 1); |
| 277 __ ret(1 * kPointerSize); | 277 __ ret(1 * kPointerSize); |
| 278 __ bind(&false_result); | 278 __ bind(&false_result); |
| 279 __ Set(rax, 0); | 279 __ Set(rax, 0); |
| (...skipping 1315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1595 __ movq(rdx, rax); | 1595 __ movq(rdx, rax); |
| 1596 | 1596 |
| 1597 // Get absolute value of exponent. | 1597 // Get absolute value of exponent. |
| 1598 NearLabel no_neg; | 1598 NearLabel no_neg; |
| 1599 __ cmpl(rax, Immediate(0)); | 1599 __ cmpl(rax, Immediate(0)); |
| 1600 __ j(greater_equal, &no_neg); | 1600 __ j(greater_equal, &no_neg); |
| 1601 __ negl(rax); | 1601 __ negl(rax); |
| 1602 __ bind(&no_neg); | 1602 __ bind(&no_neg); |
| 1603 | 1603 |
| 1604 // Load xmm1 with 1. | 1604 // Load xmm1 with 1. |
| 1605 __ movsd(xmm1, xmm3); | 1605 __ movaps(xmm1, xmm3); |
| 1606 NearLabel while_true; | 1606 NearLabel while_true; |
| 1607 NearLabel no_multiply; | 1607 NearLabel no_multiply; |
| 1608 | 1608 |
| 1609 __ bind(&while_true); | 1609 __ bind(&while_true); |
| 1610 __ shrl(rax, Immediate(1)); | 1610 __ shrl(rax, Immediate(1)); |
| 1611 __ j(not_carry, &no_multiply); | 1611 __ j(not_carry, &no_multiply); |
| 1612 __ mulsd(xmm1, xmm0); | 1612 __ mulsd(xmm1, xmm0); |
| 1613 __ bind(&no_multiply); | 1613 __ bind(&no_multiply); |
| 1614 __ mulsd(xmm0, xmm0); | 1614 __ mulsd(xmm0, xmm0); |
| 1615 __ j(not_zero, &while_true); | 1615 __ j(not_zero, &while_true); |
| 1616 | 1616 |
| 1617 // Base has the original value of the exponent - if the exponent is | 1617 // Base has the original value of the exponent - if the exponent is |
| 1618 // negative return 1/result. | 1618 // negative return 1/result. |
| 1619 __ testl(rdx, rdx); | 1619 __ testl(rdx, rdx); |
| 1620 __ j(positive, &allocate_return); | 1620 __ j(positive, &allocate_return); |
| 1621 // Special case if xmm1 has reached infinity. | 1621 // Special case if xmm1 has reached infinity. |
| 1622 __ divsd(xmm3, xmm1); | 1622 __ divsd(xmm3, xmm1); |
| 1623 __ movsd(xmm1, xmm3); | 1623 __ movaps(xmm1, xmm3); |
| 1624 __ xorpd(xmm0, xmm0); | 1624 __ xorps(xmm0, xmm0); |
| 1625 __ ucomisd(xmm0, xmm1); | 1625 __ ucomisd(xmm0, xmm1); |
| 1626 __ j(equal, &call_runtime); | 1626 __ j(equal, &call_runtime); |
| 1627 | 1627 |
| 1628 __ jmp(&allocate_return); | 1628 __ jmp(&allocate_return); |
| 1629 | 1629 |
| 1630 // Exponent (or both) is a heapnumber - no matter what we should now work | 1630 // Exponent (or both) is a heapnumber - no matter what we should now work |
| 1631 // on doubles. | 1631 // on doubles. |
| 1632 __ bind(&exponent_nonsmi); | 1632 __ bind(&exponent_nonsmi); |
| 1633 __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset), | 1633 __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset), |
| 1634 Heap::kHeapNumberMapRootIndex); | 1634 Heap::kHeapNumberMapRootIndex); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1662 // Test for -0.5. | 1662 // Test for -0.5. |
| 1663 // Load xmm2 with -0.5. | 1663 // Load xmm2 with -0.5. |
| 1664 __ movq(rcx, V8_UINT64_C(0xBFE0000000000000), RelocInfo::NONE); | 1664 __ movq(rcx, V8_UINT64_C(0xBFE0000000000000), RelocInfo::NONE); |
| 1665 __ movq(xmm2, rcx); | 1665 __ movq(xmm2, rcx); |
| 1666 // xmm2 now has -0.5. | 1666 // xmm2 now has -0.5. |
| 1667 __ ucomisd(xmm2, xmm1); | 1667 __ ucomisd(xmm2, xmm1); |
| 1668 __ j(not_equal, ¬_minus_half); | 1668 __ j(not_equal, ¬_minus_half); |
| 1669 | 1669 |
| 1670 // Calculates reciprocal of square root. | 1670 // Calculates reciprocal of square root. |
| 1671 // sqrtsd returns -0 when input is -0. ECMA spec requires +0. | 1671 // sqrtsd returns -0 when input is -0. ECMA spec requires +0. |
| 1672 __ xorpd(xmm1, xmm1); | 1672 __ xorps(xmm1, xmm1); |
| 1673 __ addsd(xmm1, xmm0); | 1673 __ addsd(xmm1, xmm0); |
| 1674 __ sqrtsd(xmm1, xmm1); | 1674 __ sqrtsd(xmm1, xmm1); |
| 1675 __ divsd(xmm3, xmm1); | 1675 __ divsd(xmm3, xmm1); |
| 1676 __ movsd(xmm1, xmm3); | 1676 __ movaps(xmm1, xmm3); |
| 1677 __ jmp(&allocate_return); | 1677 __ jmp(&allocate_return); |
| 1678 | 1678 |
| 1679 // Test for 0.5. | 1679 // Test for 0.5. |
| 1680 __ bind(¬_minus_half); | 1680 __ bind(¬_minus_half); |
| 1681 // Load xmm2 with 0.5. | 1681 // Load xmm2 with 0.5. |
| 1682 // Since xmm3 is 1 and xmm2 is -0.5 this is simply xmm2 + xmm3. | 1682 // Since xmm3 is 1 and xmm2 is -0.5 this is simply xmm2 + xmm3. |
| 1683 __ addsd(xmm2, xmm3); | 1683 __ addsd(xmm2, xmm3); |
| 1684 // xmm2 now has 0.5. | 1684 // xmm2 now has 0.5. |
| 1685 __ ucomisd(xmm2, xmm1); | 1685 __ ucomisd(xmm2, xmm1); |
| 1686 __ j(not_equal, &call_runtime); | 1686 __ j(not_equal, &call_runtime); |
| 1687 // Calculates square root. | 1687 // Calculates square root. |
| 1688 // sqrtsd returns -0 when input is -0. ECMA spec requires +0. | 1688 // sqrtsd returns -0 when input is -0. ECMA spec requires +0. |
| 1689 __ xorpd(xmm1, xmm1); | 1689 __ xorps(xmm1, xmm1); |
| 1690 __ addsd(xmm1, xmm0); | 1690 __ addsd(xmm1, xmm0); // Convert -0 to 0. |
| 1691 __ sqrtsd(xmm1, xmm1); | 1691 __ sqrtsd(xmm1, xmm1); |
| 1692 | 1692 |
| 1693 __ bind(&allocate_return); | 1693 __ bind(&allocate_return); |
| 1694 __ AllocateHeapNumber(rcx, rax, &call_runtime); | 1694 __ AllocateHeapNumber(rcx, rax, &call_runtime); |
| 1695 __ movsd(FieldOperand(rcx, HeapNumber::kValueOffset), xmm1); | 1695 __ movsd(FieldOperand(rcx, HeapNumber::kValueOffset), xmm1); |
| 1696 __ movq(rax, rcx); | 1696 __ movq(rax, rcx); |
| 1697 __ ret(2 * kPointerSize); | 1697 __ ret(2 * kPointerSize); |
| 1698 | 1698 |
| 1699 __ bind(&call_runtime); | 1699 __ bind(&call_runtime); |
| 1700 __ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1); | 1700 __ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1); |
| (...skipping 2843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4544 // Do a tail call to the rewritten stub. | 4544 // Do a tail call to the rewritten stub. |
| 4545 __ jmp(rdi); | 4545 __ jmp(rdi); |
| 4546 } | 4546 } |
| 4547 | 4547 |
| 4548 | 4548 |
| 4549 #undef __ | 4549 #undef __ |
| 4550 | 4550 |
| 4551 } } // namespace v8::internal | 4551 } } // namespace v8::internal |
| 4552 | 4552 |
| 4553 #endif // V8_TARGET_ARCH_X64 | 4553 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |