| 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 1478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1619 | 1633 |
| 1620 | 1634 |
| 1621 void Assembler::fistp_s(const Operand& adr) { | 1635 void Assembler::fistp_s(const Operand& adr) { |
| 1622 EnsureSpace ensure_space(this); | 1636 EnsureSpace ensure_space(this); |
| 1623 last_pc_ = pc_; | 1637 last_pc_ = pc_; |
| 1624 EMIT(0xDB); | 1638 EMIT(0xDB); |
| 1625 emit_operand(ebx, adr); | 1639 emit_operand(ebx, adr); |
| 1626 } | 1640 } |
| 1627 | 1641 |
| 1628 | 1642 |
| 1643 void Assembler::fisttp_s(const Operand& adr) { |
| 1644 ASSERT(CpuFeatures::IsEnabled(CpuFeatures::SSE3)); |
| 1645 EnsureSpace ensure_space(this); |
| 1646 last_pc_ = pc_; |
| 1647 EMIT(0xDB); |
| 1648 emit_operand(ecx, adr); |
| 1649 } |
| 1650 |
| 1651 |
| 1629 void Assembler::fist_s(const Operand& adr) { | 1652 void Assembler::fist_s(const Operand& adr) { |
| 1630 EnsureSpace ensure_space(this); | 1653 EnsureSpace ensure_space(this); |
| 1631 last_pc_ = pc_; | 1654 last_pc_ = pc_; |
| 1632 EMIT(0xDB); | 1655 EMIT(0xDB); |
| 1633 emit_operand(edx, adr); | 1656 emit_operand(edx, adr); |
| 1634 } | 1657 } |
| 1635 | 1658 |
| 1636 | 1659 |
| 1637 void Assembler::fistp_d(const Operand& adr) { | 1660 void Assembler::fistp_d(const Operand& adr) { |
| 1638 EnsureSpace ensure_space(this); | 1661 EnsureSpace ensure_space(this); |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1814 | 1837 |
| 1815 | 1838 |
| 1816 void Assembler::frndint() { | 1839 void Assembler::frndint() { |
| 1817 EnsureSpace ensure_space(this); | 1840 EnsureSpace ensure_space(this); |
| 1818 last_pc_ = pc_; | 1841 last_pc_ = pc_; |
| 1819 EMIT(0xD9); | 1842 EMIT(0xD9); |
| 1820 EMIT(0xFC); | 1843 EMIT(0xFC); |
| 1821 } | 1844 } |
| 1822 | 1845 |
| 1823 | 1846 |
| 1847 void Assembler::fnclex() { |
| 1848 EnsureSpace ensure_space(this); |
| 1849 last_pc_ = pc_; |
| 1850 EMIT(0xDB); |
| 1851 EMIT(0xE2); |
| 1852 } |
| 1853 |
| 1854 |
| 1824 void Assembler::sahf() { | 1855 void Assembler::sahf() { |
| 1825 EnsureSpace ensure_space(this); | 1856 EnsureSpace ensure_space(this); |
| 1826 last_pc_ = pc_; | 1857 last_pc_ = pc_; |
| 1827 EMIT(0x9E); | 1858 EMIT(0x9E); |
| 1828 } | 1859 } |
| 1829 | 1860 |
| 1830 | 1861 |
| 1831 void Assembler::setcc(Condition cc, Register reg) { | 1862 void Assembler::setcc(Condition cc, Register reg) { |
| 1832 ASSERT(reg.is_byte_register()); | 1863 ASSERT(reg.is_byte_register()); |
| 1833 EnsureSpace ensure_space(this); | 1864 EnsureSpace ensure_space(this); |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2164 ASSERT(bound_label.is_bound()); | 2195 ASSERT(bound_label.is_bound()); |
| 2165 ASSERT(0 <= position); | 2196 ASSERT(0 <= position); |
| 2166 ASSERT(position + static_cast<int>(sizeof(uint32_t)) <= pc_offset()); | 2197 ASSERT(position + static_cast<int>(sizeof(uint32_t)) <= pc_offset()); |
| 2167 ASSERT(long_at(position) == 0); // only initialize once! | 2198 ASSERT(long_at(position) == 0); // only initialize once! |
| 2168 | 2199 |
| 2169 uint32_t label_loc = reinterpret_cast<uint32_t>(addr_at(bound_label.pos())); | 2200 uint32_t label_loc = reinterpret_cast<uint32_t>(addr_at(bound_label.pos())); |
| 2170 long_at_put(position, label_loc); | 2201 long_at_put(position, label_loc); |
| 2171 } | 2202 } |
| 2172 | 2203 |
| 2173 } } // namespace v8::internal | 2204 } } // namespace v8::internal |
| OLD | NEW |