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 1589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1600 } | 1600 } |
1601 #endif | 1601 #endif |
1602 // Find the address of the rcx'th entry in the cache, i.e., &rax[rcx*16]. | 1602 // Find the address of the rcx'th entry in the cache, i.e., &rax[rcx*16]. |
1603 __ addl(rcx, rcx); | 1603 __ addl(rcx, rcx); |
1604 __ lea(rcx, Operand(rax, rcx, times_8, 0)); | 1604 __ lea(rcx, Operand(rax, rcx, times_8, 0)); |
1605 // Check if cache matches: Double value is stored in uint32_t[2] array. | 1605 // Check if cache matches: Double value is stored in uint32_t[2] array. |
1606 Label cache_miss; | 1606 Label cache_miss; |
1607 __ cmpq(rbx, Operand(rcx, 0)); | 1607 __ cmpq(rbx, Operand(rcx, 0)); |
1608 __ j(not_equal, &cache_miss, Label::kNear); | 1608 __ j(not_equal, &cache_miss, Label::kNear); |
1609 // Cache hit! | 1609 // Cache hit! |
1610 Counters* counters = masm->isolate()->counters(); | |
1611 __ IncrementCounter(counters->transcendental_cache_hit(), 1); | |
1610 __ movq(rax, Operand(rcx, 2 * kIntSize)); | 1612 __ movq(rax, Operand(rcx, 2 * kIntSize)); |
1611 if (tagged) { | 1613 if (tagged) { |
1612 __ fstp(0); // Clear FPU stack. | 1614 __ fstp(0); // Clear FPU stack. |
1613 __ ret(kPointerSize); | 1615 __ ret(kPointerSize); |
1614 } else { // UNTAGGED. | 1616 } else { // UNTAGGED. |
1615 __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset)); | 1617 __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset)); |
1616 __ Ret(); | 1618 __ Ret(); |
1617 } | 1619 } |
1618 | 1620 |
1619 __ bind(&cache_miss); | 1621 __ bind(&cache_miss); |
1622 __ IncrementCounter(counters->transcendental_cache_miss(), 1); | |
1620 // Update cache with new value. | 1623 // Update cache with new value. |
1621 if (tagged) { | 1624 if (tagged) { |
1622 __ AllocateHeapNumber(rax, rdi, &runtime_call_clear_stack); | 1625 __ AllocateHeapNumber(rax, rdi, &runtime_call_clear_stack); |
1623 } else { // UNTAGGED. | 1626 } else { // UNTAGGED. |
1624 __ AllocateHeapNumber(rax, rdi, &skip_cache); | 1627 __ AllocateHeapNumber(rax, rdi, &skip_cache); |
1625 __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm1); | 1628 __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm1); |
1626 __ fld_d(FieldOperand(rax, HeapNumber::kValueOffset)); | 1629 __ fld_d(FieldOperand(rax, HeapNumber::kValueOffset)); |
1627 } | 1630 } |
1628 GenerateOperation(masm); | 1631 GenerateOperation(masm); |
1629 __ movq(Operand(rcx, 0), rbx); | 1632 __ movq(Operand(rcx, 0), rbx); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1676 __ Ret(); | 1679 __ Ret(); |
1677 } | 1680 } |
1678 } | 1681 } |
1679 | 1682 |
1680 | 1683 |
1681 Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() { | 1684 Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() { |
1682 switch (type_) { | 1685 switch (type_) { |
1683 // Add more cases when necessary. | 1686 // Add more cases when necessary. |
1684 case TranscendentalCache::SIN: return Runtime::kMath_sin; | 1687 case TranscendentalCache::SIN: return Runtime::kMath_sin; |
1685 case TranscendentalCache::COS: return Runtime::kMath_cos; | 1688 case TranscendentalCache::COS: return Runtime::kMath_cos; |
1689 case TranscendentalCache::TAN: return Runtime::kMath_tan; | |
1686 case TranscendentalCache::LOG: return Runtime::kMath_log; | 1690 case TranscendentalCache::LOG: return Runtime::kMath_log; |
1687 default: | 1691 default: |
1688 UNIMPLEMENTED(); | 1692 UNIMPLEMENTED(); |
1689 return Runtime::kAbort; | 1693 return Runtime::kAbort; |
1690 } | 1694 } |
1691 } | 1695 } |
1692 | 1696 |
1693 | 1697 |
1694 void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) { | 1698 void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) { |
1695 // Registers: | 1699 // Registers: |
1696 // rax: Newly allocated HeapNumber, which must be preserved. | 1700 // rax: Newly allocated HeapNumber, which must be preserved. |
1697 // rbx: Bits of input double. Must be preserved. | 1701 // rbx: Bits of input double. Must be preserved. |
1698 // rcx: Pointer to cache entry. Must be preserved. | 1702 // rcx: Pointer to cache entry. Must be preserved. |
1699 // st(0): Input double | 1703 // st(0): Input double |
1700 Label done; | 1704 Label done; |
1701 if (type_ == TranscendentalCache::SIN || type_ == TranscendentalCache::COS) { | 1705 if (type_ == TranscendentalCache::SIN || |
1706 type_ == TranscendentalCache::COS || | |
1707 type_ == TranscendentalCache::TAN) { | |
1702 // Both fsin and fcos require arguments in the range +/-2^63 and | 1708 // Both fsin and fcos require arguments in the range +/-2^63 and |
1703 // return NaN for infinities and NaN. They can share all code except | 1709 // return NaN for infinities and NaN. They can share all code except |
1704 // the actual fsin/fcos operation. | 1710 // the actual fsin/fcos operation. |
1705 Label in_range; | 1711 Label in_range; |
1706 // If argument is outside the range -2^63..2^63, fsin/cos doesn't | 1712 // If argument is outside the range -2^63..2^63, fsin/cos doesn't |
1707 // work. We must reduce it to the appropriate range. | 1713 // work. We must reduce it to the appropriate range. |
1708 __ movq(rdi, rbx); | 1714 __ movq(rdi, rbx); |
1709 // Move exponent and sign bits to low bits. | 1715 // Move exponent and sign bits to low bits. |
1710 __ shr(rdi, Immediate(HeapNumber::kMantissaBits)); | 1716 __ shr(rdi, Immediate(HeapNumber::kMantissaBits)); |
1711 // Remove sign bit. | 1717 // Remove sign bit. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1761 // FPU Stack: input % 2*pi | 1767 // FPU Stack: input % 2*pi |
1762 __ movq(rax, rdi); // Restore rax, pointer to the new HeapNumber. | 1768 __ movq(rax, rdi); // Restore rax, pointer to the new HeapNumber. |
1763 __ bind(&in_range); | 1769 __ bind(&in_range); |
1764 switch (type_) { | 1770 switch (type_) { |
1765 case TranscendentalCache::SIN: | 1771 case TranscendentalCache::SIN: |
1766 __ fsin(); | 1772 __ fsin(); |
1767 break; | 1773 break; |
1768 case TranscendentalCache::COS: | 1774 case TranscendentalCache::COS: |
1769 __ fcos(); | 1775 __ fcos(); |
1770 break; | 1776 break; |
1777 case TranscendentalCache::TAN: | |
1778 // FPTAN computes tangent onto st(0) and pushes 1.0 onto the FP stack. | |
1779 __ fptan(); | |
1780 __ ffree(); | |
1781 __ fincstp(); | |
Lasse Reichstein
2011/11/25 12:46:56
If you just want to drop the top element of the fp
| |
1782 break; | |
1771 default: | 1783 default: |
1772 UNREACHABLE(); | 1784 UNREACHABLE(); |
1773 } | 1785 } |
1774 __ bind(&done); | 1786 __ bind(&done); |
1775 } else { | 1787 } else { |
1776 ASSERT(type_ == TranscendentalCache::LOG); | 1788 ASSERT(type_ == TranscendentalCache::LOG); |
1777 __ fldln2(); | 1789 __ fldln2(); |
1778 __ fxch(); | 1790 __ fxch(); |
1779 __ fyl2x(); | 1791 __ fyl2x(); |
1780 } | 1792 } |
(...skipping 4273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6054 xmm0, | 6066 xmm0, |
6055 &slow_elements); | 6067 &slow_elements); |
6056 __ ret(0); | 6068 __ ret(0); |
6057 } | 6069 } |
6058 | 6070 |
6059 #undef __ | 6071 #undef __ |
6060 | 6072 |
6061 } } // namespace v8::internal | 6073 } } // namespace v8::internal |
6062 | 6074 |
6063 #endif // V8_TARGET_ARCH_X64 | 6075 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |