| OLD | NEW |
| 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
| 2 // All Rights Reserved. | 2 // All Rights Reserved. |
| 3 // | 3 // |
| 4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
| 5 // modification, are permitted provided that the following conditions | 5 // modification, are permitted provided that the following conditions |
| 6 // are met: | 6 // are met: |
| 7 // | 7 // |
| 8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
| 9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
| 10 // | 10 // |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 XMMRegister xmm4 = { 4 }; | 62 XMMRegister xmm4 = { 4 }; |
| 63 XMMRegister xmm5 = { 5 }; | 63 XMMRegister xmm5 = { 5 }; |
| 64 XMMRegister xmm6 = { 6 }; | 64 XMMRegister xmm6 = { 6 }; |
| 65 XMMRegister xmm7 = { 7 }; | 65 XMMRegister xmm7 = { 7 }; |
| 66 | 66 |
| 67 | 67 |
| 68 // ----------------------------------------------------------------------------- | 68 // ----------------------------------------------------------------------------- |
| 69 // Implementation of CpuFeatures | 69 // Implementation of CpuFeatures |
| 70 | 70 |
| 71 // Safe default is no features. | 71 // Safe default is no features. |
| 72 uint32_t CpuFeatures::supported_ = 0; | 72 uint64_t CpuFeatures::supported_ = 0; |
| 73 uint32_t CpuFeatures::enabled_ = 0; | 73 uint64_t CpuFeatures::enabled_ = 0; |
| 74 | 74 |
| 75 | 75 |
| 76 typedef int (*F0)(); | |
| 77 | |
| 78 // The Probe method needs executable memory, so it uses Heap::CreateCode. | 76 // The Probe method needs executable memory, so it uses Heap::CreateCode. |
| 79 // Allocation failure is silent and leads to safe default. | 77 // Allocation failure is silent and leads to safe default. |
| 80 void CpuFeatures::Probe() { | 78 void CpuFeatures::Probe() { |
| 81 supported_ = 0; | 79 ASSERT(Heap::HasBeenSetup()); |
| 80 ASSERT(supported_ == 0); |
| 82 if (Serializer::enabled()) return; // No features if we might serialize. | 81 if (Serializer::enabled()) return; // No features if we might serialize. |
| 82 |
| 83 Assembler assm(NULL, 0); | 83 Assembler assm(NULL, 0); |
| 84 Label done; | 84 Label cpuid, done; |
| 85 #define __ assm. | 85 #define __ assm. |
| 86 // Save old esp, since we are going to modify the stack. | 86 // Save old esp, since we are going to modify the stack. |
| 87 __ push(ebp); | 87 __ push(ebp); |
| 88 __ pushfd(); | 88 __ pushfd(); |
| 89 __ push(ecx); | 89 __ push(ecx); |
| 90 __ push(edx); | |
| 91 __ push(ebx); | 90 __ push(ebx); |
| 92 __ mov(ebp, Operand(esp)); | 91 __ mov(ebp, Operand(esp)); |
| 92 |
| 93 // If we can modify bit 21 of the EFLAGS register, then CPUID is supported. | 93 // If we can modify bit 21 of the EFLAGS register, then CPUID is supported. |
| 94 __ pushfd(); | 94 __ pushfd(); |
| 95 __ pop(eax); | 95 __ pop(eax); |
| 96 __ mov(edx, Operand(eax)); | 96 __ mov(edx, Operand(eax)); |
| 97 __ xor_(eax, 0x200000); // Flip bit 21. | 97 __ xor_(eax, 0x200000); // Flip bit 21. |
| 98 __ push(eax); | 98 __ push(eax); |
| 99 __ popfd(); | 99 __ popfd(); |
| 100 __ pushfd(); | 100 __ pushfd(); |
| 101 __ pop(eax); | 101 __ pop(eax); |
| 102 __ xor_(eax, Operand(edx)); // Different if CPUID is supported. | 102 __ xor_(eax, Operand(edx)); // Different if CPUID is supported. |
| 103 __ j(zero, &done); | 103 __ j(not_zero, &cpuid); |
| 104 // Invoke CPUID with 1 in eax to get feature information in edx. | 104 |
| 105 // CPUID not supported. Clear the supported features in edx:eax. |
| 106 __ xor_(eax, Operand(eax)); |
| 107 __ xor_(edx, Operand(edx)); |
| 108 __ jmp(&done); |
| 109 |
| 110 // Invoke CPUID with 1 in eax to get feature information in |
| 111 // ecx:edx. Temporarily enable CPUID support because we know it's |
| 112 // safe here. |
| 113 __ bind(&cpuid); |
| 105 __ mov(eax, 1); | 114 __ mov(eax, 1); |
| 106 // Temporarily force CPUID support, since we know it is safe here. | |
| 107 supported_ = (1 << CPUID); | 115 supported_ = (1 << CPUID); |
| 108 { Scope fscope(CPUID); | 116 { Scope fscope(CPUID); |
| 109 __ cpuid(); | 117 __ cpuid(); |
| 110 } | 118 } |
| 111 supported_ = 0; | 119 supported_ = 0; |
| 112 // Return result in eax. | 120 |
| 121 // Move the result from ecx:edx to edx:eax and make sure to mark the |
| 122 // CPUID feature as supported. |
| 113 __ mov(eax, Operand(edx)); | 123 __ mov(eax, Operand(edx)); |
| 124 __ or_(eax, 1 << CPUID); |
| 125 __ mov(edx, Operand(ecx)); |
| 126 |
| 127 // Done. |
| 114 __ bind(&done); | 128 __ bind(&done); |
| 115 __ mov(esp, Operand(ebp)); | 129 __ mov(esp, Operand(ebp)); |
| 116 __ pop(ebx); | 130 __ pop(ebx); |
| 117 __ pop(edx); | |
| 118 __ pop(ecx); | 131 __ pop(ecx); |
| 119 __ popfd(); | 132 __ popfd(); |
| 120 __ pop(ebp); | 133 __ pop(ebp); |
| 121 __ ret(0); | 134 __ ret(0); |
| 122 #undef __ | 135 #undef __ |
| 136 |
| 123 CodeDesc desc; | 137 CodeDesc desc; |
| 124 assm.GetCode(&desc); | 138 assm.GetCode(&desc); |
| 125 Object* code = | 139 Object* code = |
| 126 Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB), NULL); | 140 Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB), NULL); |
| 127 if (!code->IsCode()) return; | 141 if (!code->IsCode()) return; |
| 128 F0 f = FUNCTION_CAST<F0>(Code::cast(code)->entry()); | 142 typedef uint64_t (*F0)(); |
| 129 uint32_t res = f(); | 143 F0 probe = FUNCTION_CAST<F0>(Code::cast(code)->entry()); |
| 130 supported_ = (res | (1 << CPUID)); | 144 supported_ = probe(); |
| 131 } | 145 } |
| 132 | 146 |
| 133 | 147 |
| 134 // ----------------------------------------------------------------------------- | 148 // ----------------------------------------------------------------------------- |
| 135 // Implementation of Displacement | 149 // Implementation of Displacement |
| 136 | 150 |
| 137 void Displacement::init(Label* L, Type type) { | 151 void Displacement::init(Label* L, Type type) { |
| 138 ASSERT(!L->is_bound()); | 152 ASSERT(!L->is_bound()); |
| 139 int next = 0; | 153 int next = 0; |
| 140 if (L->is_linked()) { | 154 if (L->is_linked()) { |
| (...skipping 1466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1607 | 1621 |
| 1608 | 1622 |
| 1609 void Assembler::fistp_s(const Operand& adr) { | 1623 void Assembler::fistp_s(const Operand& adr) { |
| 1610 EnsureSpace ensure_space(this); | 1624 EnsureSpace ensure_space(this); |
| 1611 last_pc_ = pc_; | 1625 last_pc_ = pc_; |
| 1612 EMIT(0xDB); | 1626 EMIT(0xDB); |
| 1613 emit_operand(ebx, adr); | 1627 emit_operand(ebx, adr); |
| 1614 } | 1628 } |
| 1615 | 1629 |
| 1616 | 1630 |
| 1631 void Assembler::fisttp_s(const Operand& adr) { |
| 1632 ASSERT(CpuFeatures::IsEnabled(CpuFeatures::SSE3)); |
| 1633 EnsureSpace ensure_space(this); |
| 1634 last_pc_ = pc_; |
| 1635 EMIT(0xDB); |
| 1636 emit_operand(ecx, adr); |
| 1637 } |
| 1638 |
| 1639 |
| 1617 void Assembler::fist_s(const Operand& adr) { | 1640 void Assembler::fist_s(const Operand& adr) { |
| 1618 EnsureSpace ensure_space(this); | 1641 EnsureSpace ensure_space(this); |
| 1619 last_pc_ = pc_; | 1642 last_pc_ = pc_; |
| 1620 EMIT(0xDB); | 1643 EMIT(0xDB); |
| 1621 emit_operand(edx, adr); | 1644 emit_operand(edx, adr); |
| 1622 } | 1645 } |
| 1623 | 1646 |
| 1624 | 1647 |
| 1625 void Assembler::fistp_d(const Operand& adr) { | 1648 void Assembler::fistp_d(const Operand& adr) { |
| 1626 EnsureSpace ensure_space(this); | 1649 EnsureSpace ensure_space(this); |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1802 | 1825 |
| 1803 | 1826 |
| 1804 void Assembler::frndint() { | 1827 void Assembler::frndint() { |
| 1805 EnsureSpace ensure_space(this); | 1828 EnsureSpace ensure_space(this); |
| 1806 last_pc_ = pc_; | 1829 last_pc_ = pc_; |
| 1807 EMIT(0xD9); | 1830 EMIT(0xD9); |
| 1808 EMIT(0xFC); | 1831 EMIT(0xFC); |
| 1809 } | 1832 } |
| 1810 | 1833 |
| 1811 | 1834 |
| 1835 void Assembler::fnclex() { |
| 1836 EnsureSpace ensure_space(this); |
| 1837 last_pc_ = pc_; |
| 1838 EMIT(0xDB); |
| 1839 EMIT(0xE2); |
| 1840 } |
| 1841 |
| 1842 |
| 1812 void Assembler::sahf() { | 1843 void Assembler::sahf() { |
| 1813 EnsureSpace ensure_space(this); | 1844 EnsureSpace ensure_space(this); |
| 1814 last_pc_ = pc_; | 1845 last_pc_ = pc_; |
| 1815 EMIT(0x9E); | 1846 EMIT(0x9E); |
| 1816 } | 1847 } |
| 1817 | 1848 |
| 1818 | 1849 |
| 1819 void Assembler::cvttss2si(Register dst, const Operand& src) { | 1850 void Assembler::cvttss2si(Register dst, const Operand& src) { |
| 1820 ASSERT(CpuFeatures::IsEnabled(CpuFeatures::SSE2)); | 1851 ASSERT(CpuFeatures::IsEnabled(CpuFeatures::SSE2)); |
| 1821 EnsureSpace ensure_space(this); | 1852 EnsureSpace ensure_space(this); |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2142 ASSERT(bound_label.is_bound()); | 2173 ASSERT(bound_label.is_bound()); |
| 2143 ASSERT(0 <= position); | 2174 ASSERT(0 <= position); |
| 2144 ASSERT(position + static_cast<int>(sizeof(uint32_t)) <= pc_offset()); | 2175 ASSERT(position + static_cast<int>(sizeof(uint32_t)) <= pc_offset()); |
| 2145 ASSERT(long_at(position) == 0); // only initialize once! | 2176 ASSERT(long_at(position) == 0); // only initialize once! |
| 2146 | 2177 |
| 2147 uint32_t label_loc = reinterpret_cast<uint32_t>(addr_at(bound_label.pos())); | 2178 uint32_t label_loc = reinterpret_cast<uint32_t>(addr_at(bound_label.pos())); |
| 2148 long_at_put(position, label_loc); | 2179 long_at_put(position, label_loc); |
| 2149 } | 2180 } |
| 2150 | 2181 |
| 2151 } } // namespace v8::internal | 2182 } } // namespace v8::internal |
| OLD | NEW |