| 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 | 32 |
| (...skipping 1026 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1111 void Assembler::andpd(XmmRegister dst, XmmRegister src) { | 1059 void Assembler::andpd(XmmRegister dst, XmmRegister src) { |
| 1112 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1060 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1113 EmitUint8(0x66); | 1061 EmitUint8(0x66); |
| 1114 EmitUint8(0x0F); | 1062 EmitUint8(0x0F); |
| 1115 EmitUint8(0x54); | 1063 EmitUint8(0x54); |
| 1116 EmitXmmRegisterOperand(dst, src); | 1064 EmitXmmRegisterOperand(dst, src); |
| 1117 } | 1065 } |
| 1118 | 1066 |
| 1119 | 1067 |
| 1120 void Assembler::pextrd(Register dst, XmmRegister src, const Immediate& imm) { | 1068 void Assembler::pextrd(Register dst, XmmRegister src, const Immediate& imm) { |
| 1121 ASSERT(CPUFeatures::sse4_1_supported()); | 1069 ASSERT(TargetCPUFeatures::sse4_1_supported()); |
| 1122 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1070 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1123 EmitUint8(0x66); | 1071 EmitUint8(0x66); |
| 1124 EmitUint8(0x0F); | 1072 EmitUint8(0x0F); |
| 1125 EmitUint8(0x3A); | 1073 EmitUint8(0x3A); |
| 1126 EmitUint8(0x16); | 1074 EmitUint8(0x16); |
| 1127 EmitOperand(src, Operand(dst)); | 1075 EmitOperand(src, Operand(dst)); |
| 1128 ASSERT(imm.is_uint8()); | 1076 ASSERT(imm.is_uint8()); |
| 1129 EmitUint8(imm.value()); | 1077 EmitUint8(imm.value()); |
| 1130 } | 1078 } |
| 1131 | 1079 |
| 1132 | 1080 |
| 1133 void Assembler::pmovsxdq(XmmRegister dst, XmmRegister src) { | 1081 void Assembler::pmovsxdq(XmmRegister dst, XmmRegister src) { |
| 1134 ASSERT(CPUFeatures::sse4_1_supported()); | 1082 ASSERT(TargetCPUFeatures::sse4_1_supported()); |
| 1135 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1083 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1136 EmitUint8(0x66); | 1084 EmitUint8(0x66); |
| 1137 EmitUint8(0x0F); | 1085 EmitUint8(0x0F); |
| 1138 EmitUint8(0x38); | 1086 EmitUint8(0x38); |
| 1139 EmitUint8(0x25); | 1087 EmitUint8(0x25); |
| 1140 EmitXmmRegisterOperand(dst, src); | 1088 EmitXmmRegisterOperand(dst, src); |
| 1141 } | 1089 } |
| 1142 | 1090 |
| 1143 | 1091 |
| 1144 void Assembler::pcmpeqq(XmmRegister dst, XmmRegister src) { | 1092 void Assembler::pcmpeqq(XmmRegister dst, XmmRegister src) { |
| 1145 ASSERT(CPUFeatures::sse4_1_supported()); | 1093 ASSERT(TargetCPUFeatures::sse4_1_supported()); |
| 1146 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1094 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1147 EmitUint8(0x66); | 1095 EmitUint8(0x66); |
| 1148 EmitUint8(0x0F); | 1096 EmitUint8(0x0F); |
| 1149 EmitUint8(0x38); | 1097 EmitUint8(0x38); |
| 1150 EmitUint8(0x29); | 1098 EmitUint8(0x29); |
| 1151 EmitXmmRegisterOperand(dst, src); | 1099 EmitXmmRegisterOperand(dst, src); |
| 1152 } | 1100 } |
| 1153 | 1101 |
| 1154 | 1102 |
| 1155 void Assembler::pxor(XmmRegister dst, XmmRegister src) { | 1103 void Assembler::pxor(XmmRegister dst, XmmRegister src) { |
| 1156 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1104 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1157 EmitUint8(0x66); | 1105 EmitUint8(0x66); |
| 1158 EmitUint8(0x0F); | 1106 EmitUint8(0x0F); |
| 1159 EmitUint8(0xEF); | 1107 EmitUint8(0xEF); |
| 1160 EmitXmmRegisterOperand(dst, src); | 1108 EmitXmmRegisterOperand(dst, src); |
| 1161 } | 1109 } |
| 1162 | 1110 |
| 1163 | 1111 |
| 1164 void Assembler::roundsd(XmmRegister dst, XmmRegister src, RoundingMode mode) { | 1112 void Assembler::roundsd(XmmRegister dst, XmmRegister src, RoundingMode mode) { |
| 1165 ASSERT(CPUFeatures::sse4_1_supported()); | 1113 ASSERT(TargetCPUFeatures::sse4_1_supported()); |
| 1166 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1114 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1167 EmitUint8(0x66); | 1115 EmitUint8(0x66); |
| 1168 EmitUint8(0x0F); | 1116 EmitUint8(0x0F); |
| 1169 EmitUint8(0x3A); | 1117 EmitUint8(0x3A); |
| 1170 EmitUint8(0x0B); | 1118 EmitUint8(0x0B); |
| 1171 EmitXmmRegisterOperand(dst, src); | 1119 EmitXmmRegisterOperand(dst, src); |
| 1172 // Mask precision exeption. | 1120 // Mask precision exeption. |
| 1173 EmitUint8(static_cast<uint8_t>(mode) | 0x8); | 1121 EmitUint8(static_cast<uint8_t>(mode) | 0x8); |
| 1174 } | 1122 } |
| 1175 | 1123 |
| (...skipping 1347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2523 | 2471 |
| 2524 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 2472 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
| 2525 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); | 2473 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); |
| 2526 return xmm_reg_names[reg]; | 2474 return xmm_reg_names[reg]; |
| 2527 } | 2475 } |
| 2528 | 2476 |
| 2529 | 2477 |
| 2530 } // namespace dart | 2478 } // namespace dart |
| 2531 | 2479 |
| 2532 #endif // defined TARGET_ARCH_IA32 | 2480 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |