OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
| 10 #include "vm/cpu.h" |
10 #include "vm/heap.h" | 11 #include "vm/heap.h" |
11 #include "vm/memory_region.h" | 12 #include "vm/memory_region.h" |
12 #include "vm/runtime_entry.h" | 13 #include "vm/runtime_entry.h" |
13 #include "vm/stack_frame.h" | 14 #include "vm/stack_frame.h" |
14 #include "vm/stub_code.h" | 15 #include "vm/stub_code.h" |
15 | 16 |
16 namespace dart { | 17 namespace dart { |
17 | 18 |
18 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); | 19 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); |
19 DEFINE_FLAG(bool, use_sse41, true, "Use SSE 4.1 if available"); | |
20 DECLARE_FLAG(bool, inline_alloc); | 20 DECLARE_FLAG(bool, inline_alloc); |
21 | 21 |
22 | 22 |
23 bool CPUFeatures::sse2_supported_ = false; | |
24 bool CPUFeatures::sse4_1_supported_ = false; | |
25 #ifdef DEBUG | |
26 bool CPUFeatures::initialized_ = false; | |
27 #endif | |
28 | |
29 | |
30 bool CPUFeatures::sse2_supported() { | |
31 DEBUG_ASSERT(initialized_); | |
32 return sse2_supported_; | |
33 } | |
34 | |
35 | |
36 bool CPUFeatures::sse4_1_supported() { | |
37 DEBUG_ASSERT(initialized_); | |
38 return sse4_1_supported_ && FLAG_use_sse41; | |
39 } | |
40 | |
41 | |
42 #define __ assembler. | |
43 | |
44 void CPUFeatures::InitOnce() { | |
45 Assembler assembler; | |
46 __ pushl(EBP); | |
47 __ pushl(EBX); | |
48 __ movl(EBP, ESP); | |
49 // Get feature information in ECX:EDX and return it in EDX:EAX. | |
50 __ movl(EAX, Immediate(1)); | |
51 __ cpuid(); | |
52 __ movl(EAX, EDX); | |
53 __ movl(EDX, ECX); | |
54 __ movl(ESP, EBP); | |
55 __ popl(EBX); | |
56 __ popl(EBP); | |
57 __ ret(); | |
58 | |
59 const Code& code = | |
60 Code::Handle(Code::FinalizeCode("DetectCPUFeatures", &assembler)); | |
61 Instructions& instructions = Instructions::Handle(code.instructions()); | |
62 typedef uint64_t (*DetectCPUFeatures)(); | |
63 uint64_t features = | |
64 reinterpret_cast<DetectCPUFeatures>(instructions.EntryPoint())(); | |
65 sse2_supported_ = (features & kSSE2BitMask) != 0; | |
66 sse4_1_supported_ = (features & kSSE4_1BitMask) != 0; | |
67 #ifdef DEBUG | |
68 initialized_ = true; | |
69 #endif | |
70 } | |
71 | |
72 #undef __ | |
73 | |
74 | |
75 class DirectCallRelocation : public AssemblerFixup { | 23 class DirectCallRelocation : public AssemblerFixup { |
76 public: | 24 public: |
77 void Process(const MemoryRegion& region, intptr_t position) { | 25 void Process(const MemoryRegion& region, intptr_t position) { |
78 // Direct calls are relative to the following instruction on x86. | 26 // Direct calls are relative to the following instruction on x86. |
79 int32_t pointer = region.Load<int32_t>(position); | 27 int32_t pointer = region.Load<int32_t>(position); |
80 int32_t delta = region.start() + position + sizeof(int32_t); | 28 int32_t delta = region.start() + position + sizeof(int32_t); |
81 region.Store<int32_t>(position, pointer - delta); | 29 region.Store<int32_t>(position, pointer - delta); |
82 } | 30 } |
83 | 31 |
84 virtual bool IsPointerOffset() const { return false; } | 32 virtual bool IsPointerOffset() const { return false; } |
(...skipping 1130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1215 void Assembler::andpd(XmmRegister dst, XmmRegister src) { | 1163 void Assembler::andpd(XmmRegister dst, XmmRegister src) { |
1216 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1164 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1217 EmitUint8(0x66); | 1165 EmitUint8(0x66); |
1218 EmitUint8(0x0F); | 1166 EmitUint8(0x0F); |
1219 EmitUint8(0x54); | 1167 EmitUint8(0x54); |
1220 EmitXmmRegisterOperand(dst, src); | 1168 EmitXmmRegisterOperand(dst, src); |
1221 } | 1169 } |
1222 | 1170 |
1223 | 1171 |
1224 void Assembler::pextrd(Register dst, XmmRegister src, const Immediate& imm) { | 1172 void Assembler::pextrd(Register dst, XmmRegister src, const Immediate& imm) { |
1225 ASSERT(CPUFeatures::sse4_1_supported()); | 1173 ASSERT(TargetCPUFeatures::sse4_1_supported()); |
1226 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1174 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1227 EmitUint8(0x66); | 1175 EmitUint8(0x66); |
1228 EmitUint8(0x0F); | 1176 EmitUint8(0x0F); |
1229 EmitUint8(0x3A); | 1177 EmitUint8(0x3A); |
1230 EmitUint8(0x16); | 1178 EmitUint8(0x16); |
1231 EmitOperand(src, Operand(dst)); | 1179 EmitOperand(src, Operand(dst)); |
1232 ASSERT(imm.is_uint8()); | 1180 ASSERT(imm.is_uint8()); |
1233 EmitUint8(imm.value()); | 1181 EmitUint8(imm.value()); |
1234 } | 1182 } |
1235 | 1183 |
1236 | 1184 |
1237 void Assembler::pmovsxdq(XmmRegister dst, XmmRegister src) { | 1185 void Assembler::pmovsxdq(XmmRegister dst, XmmRegister src) { |
1238 ASSERT(CPUFeatures::sse4_1_supported()); | 1186 ASSERT(TargetCPUFeatures::sse4_1_supported()); |
1239 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1187 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1240 EmitUint8(0x66); | 1188 EmitUint8(0x66); |
1241 EmitUint8(0x0F); | 1189 EmitUint8(0x0F); |
1242 EmitUint8(0x38); | 1190 EmitUint8(0x38); |
1243 EmitUint8(0x25); | 1191 EmitUint8(0x25); |
1244 EmitXmmRegisterOperand(dst, src); | 1192 EmitXmmRegisterOperand(dst, src); |
1245 } | 1193 } |
1246 | 1194 |
1247 | 1195 |
1248 void Assembler::pcmpeqq(XmmRegister dst, XmmRegister src) { | 1196 void Assembler::pcmpeqq(XmmRegister dst, XmmRegister src) { |
1249 ASSERT(CPUFeatures::sse4_1_supported()); | 1197 ASSERT(TargetCPUFeatures::sse4_1_supported()); |
1250 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1198 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1251 EmitUint8(0x66); | 1199 EmitUint8(0x66); |
1252 EmitUint8(0x0F); | 1200 EmitUint8(0x0F); |
1253 EmitUint8(0x38); | 1201 EmitUint8(0x38); |
1254 EmitUint8(0x29); | 1202 EmitUint8(0x29); |
1255 EmitXmmRegisterOperand(dst, src); | 1203 EmitXmmRegisterOperand(dst, src); |
1256 } | 1204 } |
1257 | 1205 |
1258 | 1206 |
1259 void Assembler::pxor(XmmRegister dst, XmmRegister src) { | 1207 void Assembler::pxor(XmmRegister dst, XmmRegister src) { |
1260 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1208 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1261 EmitUint8(0x66); | 1209 EmitUint8(0x66); |
1262 EmitUint8(0x0F); | 1210 EmitUint8(0x0F); |
1263 EmitUint8(0xEF); | 1211 EmitUint8(0xEF); |
1264 EmitXmmRegisterOperand(dst, src); | 1212 EmitXmmRegisterOperand(dst, src); |
1265 } | 1213 } |
1266 | 1214 |
1267 | 1215 |
1268 void Assembler::roundsd(XmmRegister dst, XmmRegister src, RoundingMode mode) { | 1216 void Assembler::roundsd(XmmRegister dst, XmmRegister src, RoundingMode mode) { |
1269 ASSERT(CPUFeatures::sse4_1_supported()); | 1217 ASSERT(TargetCPUFeatures::sse4_1_supported()); |
1270 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1218 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1271 EmitUint8(0x66); | 1219 EmitUint8(0x66); |
1272 EmitUint8(0x0F); | 1220 EmitUint8(0x0F); |
1273 EmitUint8(0x3A); | 1221 EmitUint8(0x3A); |
1274 EmitUint8(0x0B); | 1222 EmitUint8(0x0B); |
1275 EmitXmmRegisterOperand(dst, src); | 1223 EmitXmmRegisterOperand(dst, src); |
1276 // Mask precision exeption. | 1224 // Mask precision exeption. |
1277 EmitUint8(static_cast<uint8_t>(mode) | 0x8); | 1225 EmitUint8(static_cast<uint8_t>(mode) | 0x8); |
1278 } | 1226 } |
1279 | 1227 |
(...skipping 1420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2700 | 2648 |
2701 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 2649 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
2702 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); | 2650 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); |
2703 return xmm_reg_names[reg]; | 2651 return xmm_reg_names[reg]; |
2704 } | 2652 } |
2705 | 2653 |
2706 | 2654 |
2707 } // namespace dart | 2655 } // namespace dart |
2708 | 2656 |
2709 #endif // defined TARGET_ARCH_IA32 | 2657 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |