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 |