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" | |
11 #include "vm/heap.h" | 10 #include "vm/heap.h" |
12 #include "vm/memory_region.h" | 11 #include "vm/memory_region.h" |
13 #include "vm/runtime_entry.h" | 12 #include "vm/runtime_entry.h" |
14 #include "vm/stack_frame.h" | 13 #include "vm/stack_frame.h" |
15 #include "vm/stub_code.h" | 14 #include "vm/stub_code.h" |
16 | 15 |
17 namespace dart { | 16 namespace dart { |
18 | 17 |
19 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); | 18 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 |
23 class DirectCallRelocation : public AssemblerFixup { | 75 class DirectCallRelocation : public AssemblerFixup { |
24 public: | 76 public: |
25 void Process(const MemoryRegion& region, intptr_t position) { | 77 void Process(const MemoryRegion& region, intptr_t position) { |
26 // Direct calls are relative to the following instruction on x86. | 78 // Direct calls are relative to the following instruction on x86. |
27 int32_t pointer = region.Load<int32_t>(position); | 79 int32_t pointer = region.Load<int32_t>(position); |
28 int32_t delta = region.start() + position + sizeof(int32_t); | 80 int32_t delta = region.start() + position + sizeof(int32_t); |
29 region.Store<int32_t>(position, pointer - delta); | 81 region.Store<int32_t>(position, pointer - delta); |
30 } | 82 } |
31 | 83 |
32 virtual bool IsPointerOffset() const { return false; } | 84 virtual bool IsPointerOffset() const { return false; } |
(...skipping 1130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1163 void Assembler::andpd(XmmRegister dst, XmmRegister src) { | 1215 void Assembler::andpd(XmmRegister dst, XmmRegister src) { |
1164 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1216 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1165 EmitUint8(0x66); | 1217 EmitUint8(0x66); |
1166 EmitUint8(0x0F); | 1218 EmitUint8(0x0F); |
1167 EmitUint8(0x54); | 1219 EmitUint8(0x54); |
1168 EmitXmmRegisterOperand(dst, src); | 1220 EmitXmmRegisterOperand(dst, src); |
1169 } | 1221 } |
1170 | 1222 |
1171 | 1223 |
1172 void Assembler::pextrd(Register dst, XmmRegister src, const Immediate& imm) { | 1224 void Assembler::pextrd(Register dst, XmmRegister src, const Immediate& imm) { |
1173 ASSERT(TargetCPUFeatures::sse4_1_supported()); | 1225 ASSERT(CPUFeatures::sse4_1_supported()); |
1174 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1226 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1175 EmitUint8(0x66); | 1227 EmitUint8(0x66); |
1176 EmitUint8(0x0F); | 1228 EmitUint8(0x0F); |
1177 EmitUint8(0x3A); | 1229 EmitUint8(0x3A); |
1178 EmitUint8(0x16); | 1230 EmitUint8(0x16); |
1179 EmitOperand(src, Operand(dst)); | 1231 EmitOperand(src, Operand(dst)); |
1180 ASSERT(imm.is_uint8()); | 1232 ASSERT(imm.is_uint8()); |
1181 EmitUint8(imm.value()); | 1233 EmitUint8(imm.value()); |
1182 } | 1234 } |
1183 | 1235 |
1184 | 1236 |
1185 void Assembler::pmovsxdq(XmmRegister dst, XmmRegister src) { | 1237 void Assembler::pmovsxdq(XmmRegister dst, XmmRegister src) { |
1186 ASSERT(TargetCPUFeatures::sse4_1_supported()); | 1238 ASSERT(CPUFeatures::sse4_1_supported()); |
1187 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1239 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1188 EmitUint8(0x66); | 1240 EmitUint8(0x66); |
1189 EmitUint8(0x0F); | 1241 EmitUint8(0x0F); |
1190 EmitUint8(0x38); | 1242 EmitUint8(0x38); |
1191 EmitUint8(0x25); | 1243 EmitUint8(0x25); |
1192 EmitXmmRegisterOperand(dst, src); | 1244 EmitXmmRegisterOperand(dst, src); |
1193 } | 1245 } |
1194 | 1246 |
1195 | 1247 |
1196 void Assembler::pcmpeqq(XmmRegister dst, XmmRegister src) { | 1248 void Assembler::pcmpeqq(XmmRegister dst, XmmRegister src) { |
1197 ASSERT(TargetCPUFeatures::sse4_1_supported()); | 1249 ASSERT(CPUFeatures::sse4_1_supported()); |
1198 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1250 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1199 EmitUint8(0x66); | 1251 EmitUint8(0x66); |
1200 EmitUint8(0x0F); | 1252 EmitUint8(0x0F); |
1201 EmitUint8(0x38); | 1253 EmitUint8(0x38); |
1202 EmitUint8(0x29); | 1254 EmitUint8(0x29); |
1203 EmitXmmRegisterOperand(dst, src); | 1255 EmitXmmRegisterOperand(dst, src); |
1204 } | 1256 } |
1205 | 1257 |
1206 | 1258 |
1207 void Assembler::pxor(XmmRegister dst, XmmRegister src) { | 1259 void Assembler::pxor(XmmRegister dst, XmmRegister src) { |
1208 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1260 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1209 EmitUint8(0x66); | 1261 EmitUint8(0x66); |
1210 EmitUint8(0x0F); | 1262 EmitUint8(0x0F); |
1211 EmitUint8(0xEF); | 1263 EmitUint8(0xEF); |
1212 EmitXmmRegisterOperand(dst, src); | 1264 EmitXmmRegisterOperand(dst, src); |
1213 } | 1265 } |
1214 | 1266 |
1215 | 1267 |
1216 void Assembler::roundsd(XmmRegister dst, XmmRegister src, RoundingMode mode) { | 1268 void Assembler::roundsd(XmmRegister dst, XmmRegister src, RoundingMode mode) { |
1217 ASSERT(TargetCPUFeatures::sse4_1_supported()); | 1269 ASSERT(CPUFeatures::sse4_1_supported()); |
1218 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1270 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1219 EmitUint8(0x66); | 1271 EmitUint8(0x66); |
1220 EmitUint8(0x0F); | 1272 EmitUint8(0x0F); |
1221 EmitUint8(0x3A); | 1273 EmitUint8(0x3A); |
1222 EmitUint8(0x0B); | 1274 EmitUint8(0x0B); |
1223 EmitXmmRegisterOperand(dst, src); | 1275 EmitXmmRegisterOperand(dst, src); |
1224 // Mask precision exeption. | 1276 // Mask precision exeption. |
1225 EmitUint8(static_cast<uint8_t>(mode) | 0x8); | 1277 EmitUint8(static_cast<uint8_t>(mode) | 0x8); |
1226 } | 1278 } |
1227 | 1279 |
(...skipping 1420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2648 | 2700 |
2649 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 2701 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
2650 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); | 2702 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); |
2651 return xmm_reg_names[reg]; | 2703 return xmm_reg_names[reg]; |
2652 } | 2704 } |
2653 | 2705 |
2654 | 2706 |
2655 } // namespace dart | 2707 } // namespace dart |
2656 | 2708 |
2657 #endif // defined TARGET_ARCH_IA32 | 2709 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |