Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(617)

Side by Side Diff: src/ia32/assembler-ia32.cc

Issue 23401002: Fix the CPU feature detection. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Improve cpuinfo parsing. Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/cpu.cc ('k') | src/mips/assembler-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 ASSERT(!initialized_); 94 ASSERT(!initialized_);
95 ASSERT(supported_ == 0); 95 ASSERT(supported_ == 0);
96 #ifdef DEBUG 96 #ifdef DEBUG
97 initialized_ = true; 97 initialized_ = true;
98 #endif 98 #endif
99 if (Serializer::enabled()) { 99 if (Serializer::enabled()) {
100 supported_ |= OS::CpuFeaturesImpliedByPlatform(); 100 supported_ |= OS::CpuFeaturesImpliedByPlatform();
101 return; // No features if we might serialize. 101 return; // No features if we might serialize.
102 } 102 }
103 103
104 const int kBufferSize = 4 * KB; 104 uint64_t probed_features = 0;
105 VirtualMemory* memory = new VirtualMemory(kBufferSize); 105 CPU cpu;
106 if (!memory->IsReserved()) { 106 if (cpu.has_sse41()) {
107 delete memory; 107 probed_features |= static_cast<uint64_t>(1) << SSE4_1;
108 return;
109 } 108 }
110 ASSERT(memory->size() >= static_cast<size_t>(kBufferSize)); 109 if (cpu.has_sse3()) {
111 if (!memory->Commit(memory->address(), kBufferSize, true/*executable*/)) { 110 probed_features |= static_cast<uint64_t>(1) << SSE3;
112 delete memory; 111 }
113 return; 112 if (cpu.has_sse2()) {
113 probed_features |= static_cast<uint64_t>(1) << SSE2;
114 }
115 if (cpu.has_cmov()) {
116 probed_features |= static_cast<uint64_t>(1) << CMOV;
114 } 117 }
115 118
116 Assembler assm(NULL, memory->address(), kBufferSize); 119 // SAHF must be available in compat/legacy mode.
117 Label cpuid, done; 120 ASSERT(cpu.has_sahf());
118 #define __ assm. 121 probed_features |= static_cast<uint64_t>(1) << SAHF;
119 // Save old esp, since we are going to modify the stack.
120 __ push(ebp);
121 __ pushfd();
122 __ push(ecx);
123 __ push(ebx);
124 __ mov(ebp, esp);
125 122
126 // If we can modify bit 21 of the EFLAGS register, then CPUID is supported.
127 __ pushfd();
128 __ pop(eax);
129 __ mov(edx, eax);
130 __ xor_(eax, 0x200000); // Flip bit 21.
131 __ push(eax);
132 __ popfd();
133 __ pushfd();
134 __ pop(eax);
135 __ xor_(eax, edx); // Different if CPUID is supported.
136 __ j(not_zero, &cpuid);
137
138 // CPUID not supported. Clear the supported features in edx:eax.
139 __ xor_(eax, eax);
140 __ xor_(edx, edx);
141 __ jmp(&done);
142
143 // Invoke CPUID with 1 in eax to get feature information in
144 // ecx:edx. Temporarily enable CPUID support because we know it's
145 // safe here.
146 __ bind(&cpuid);
147 __ mov(eax, 1);
148 supported_ = (1 << CPUID);
149 { CpuFeatureScope fscope(&assm, CPUID);
150 __ cpuid();
151 }
152 supported_ = 0;
153
154 // Move the result from ecx:edx to edx:eax and make sure to mark the
155 // CPUID feature as supported.
156 __ mov(eax, edx);
157 __ or_(eax, 1 << CPUID);
158 __ mov(edx, ecx);
159
160 // Done.
161 __ bind(&done);
162 __ mov(esp, ebp);
163 __ pop(ebx);
164 __ pop(ecx);
165 __ popfd();
166 __ pop(ebp);
167 __ ret(0);
168 #undef __
169
170 typedef uint64_t (*F0)();
171 F0 probe = FUNCTION_CAST<F0>(reinterpret_cast<Address>(memory->address()));
172 uint64_t probed_features = probe();
173 uint64_t platform_features = OS::CpuFeaturesImpliedByPlatform(); 123 uint64_t platform_features = OS::CpuFeaturesImpliedByPlatform();
174 supported_ = probed_features | platform_features; 124 supported_ = probed_features | platform_features;
175 found_by_runtime_probing_only_ = probed_features & ~platform_features; 125 found_by_runtime_probing_only_ = probed_features & ~platform_features;
176
177 delete memory;
178 } 126 }
179 127
180 128
181 // ----------------------------------------------------------------------------- 129 // -----------------------------------------------------------------------------
182 // Implementation of Displacement 130 // Implementation of Displacement
183 131
184 void Displacement::init(Label* L, Type type) { 132 void Displacement::init(Label* L, Type type) {
185 ASSERT(!L->is_bound()); 133 ASSERT(!L->is_bound());
186 int next = 0; 134 int next = 0;
187 if (L->is_linked()) { 135 if (L->is_linked()) {
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 } 415 }
468 } 416 }
469 417
470 418
471 void Assembler::CodeTargetAlign() { 419 void Assembler::CodeTargetAlign() {
472 Align(16); // Preferred alignment of jump targets on ia32. 420 Align(16); // Preferred alignment of jump targets on ia32.
473 } 421 }
474 422
475 423
476 void Assembler::cpuid() { 424 void Assembler::cpuid() {
477 ASSERT(IsEnabled(CPUID));
478 EnsureSpace ensure_space(this); 425 EnsureSpace ensure_space(this);
479 EMIT(0x0F); 426 EMIT(0x0F);
480 EMIT(0xA2); 427 EMIT(0xA2);
481 } 428 }
482 429
483 430
484 void Assembler::pushad() { 431 void Assembler::pushad() {
485 EnsureSpace ensure_space(this); 432 EnsureSpace ensure_space(this);
486 EMIT(0x60); 433 EMIT(0x60);
487 } 434 }
(...skipping 2219 matching lines...) Expand 10 before | Expand all | Expand 10 after
2707 fprintf(coverage_log, "%s\n", file_line); 2654 fprintf(coverage_log, "%s\n", file_line);
2708 fflush(coverage_log); 2655 fflush(coverage_log);
2709 } 2656 }
2710 } 2657 }
2711 2658
2712 #endif 2659 #endif
2713 2660
2714 } } // namespace v8::internal 2661 } } // namespace v8::internal
2715 2662
2716 #endif // V8_TARGET_ARCH_IA32 2663 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/cpu.cc ('k') | src/mips/assembler-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698