Chromium Code Reviews| Index: runtime/vm/assembler_x64.cc |
| =================================================================== |
| --- runtime/vm/assembler_x64.cc (revision 12828) |
| +++ runtime/vm/assembler_x64.cc (working copy) |
| @@ -16,8 +16,59 @@ |
| DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); |
| DEFINE_FLAG(bool, code_comments, false, |
| "Include comments into code and disassembly"); |
| +DEFINE_FLAG(bool, use_sse41, true, "Use SSE 4.1 if available"); |
| +bool CPUFeatures::sse3_supported_ = false; |
| +bool CPUFeatures::sse4_1_supported_ = false; |
| +bool CPUFeatures::initialized_ = false; |
| + |
| + |
| +bool CPUFeatures::sse3_supported() { |
| + ASSERT(initialized_); |
| + return sse3_supported_; |
| +} |
| + |
| + |
| +bool CPUFeatures::sse4_1_supported() { |
| + ASSERT(initialized_); |
| + return sse4_1_supported_; |
| +} |
| + |
| + |
| +#define __ assembler. |
| + |
| +void CPUFeatures::InitOnce() { |
| + Assembler assembler; |
| + __ pushq(RBP); |
| + __ pushq(RBX); |
| + __ movq(RBP, RSP); |
| + // Get feature information in ECX:EDX and return it in RAX. |
|
srdjan
2012/09/25 17:12:25
RCX, RDX ?
Florian Schneider
2012/09/26 09:03:16
That is intentional according to the spec: cpuid o
|
| + __ movq(RAX, Immediate(1)); |
| + __ cpuid(); |
| + __ movl(RAX, RCX); // Zero extended. |
| + __ shlq(RAX, Immediate(32)); |
| + __ movl(RCX, RDX); // Zero extended. |
| + __ orq(RAX, RCX); |
| + __ movq(RSP, RBP); |
| + __ popq(RBX); |
| + __ popq(RBP); |
| + __ ret(); |
| + |
| + const Code& code = |
| + Code::Handle(Code::FinalizeCode("DetectCPUFeatures", &assembler)); |
| + Instructions& instructions = Instructions::Handle(code.instructions()); |
| + typedef uint64_t (*DetectCPUFeatures)(); |
| + uint64_t features = |
| + reinterpret_cast<DetectCPUFeatures>(instructions.EntryPoint())(); |
| + sse3_supported_ = (features & kSSE3BitMask) != 0; |
| + sse4_1_supported_ = (features & kSSE4_1BitMask) != 0; |
| + initialized_ = true; |
| +} |
| + |
| +#undef __ |
| + |
| + |
| void Assembler::InitializeMemoryWithBreakpoints(uword data, int length) { |
| memset(reinterpret_cast<void*>(data), Instr::kBreakPointInstruction, length); |
| } |
| @@ -1473,6 +1524,13 @@ |
| } |
| +void Assembler::cpuid() { |
| + AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| + EmitUint8(0x0F); |
| + EmitUint8(0xA2); |
| +} |
| + |
| + |
| void Assembler::CompareRegisters(Register a, Register b) { |
| cmpq(a, b); |
| } |