OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 25 matching lines...) Expand all Loading... |
36 namespace internal { | 36 namespace internal { |
37 | 37 |
38 // ----------------------------------------------------------------------------- | 38 // ----------------------------------------------------------------------------- |
39 // Implementation of CpuFeatures | 39 // Implementation of CpuFeatures |
40 | 40 |
41 | 41 |
42 #ifdef DEBUG | 42 #ifdef DEBUG |
43 bool CpuFeatures::initialized_ = false; | 43 bool CpuFeatures::initialized_ = false; |
44 #endif | 44 #endif |
45 uint64_t CpuFeatures::supported_ = CpuFeatures::kDefaultCpuFeatures; | 45 uint64_t CpuFeatures::supported_ = CpuFeatures::kDefaultCpuFeatures; |
46 uint64_t CpuFeatures::found_by_runtime_probing_ = 0; | 46 uint64_t CpuFeatures::found_by_runtime_probing_only_ = 0; |
47 | 47 |
48 | 48 |
49 ExternalReference ExternalReference::cpu_features() { | 49 ExternalReference ExternalReference::cpu_features() { |
50 ASSERT(CpuFeatures::initialized_); | 50 ASSERT(CpuFeatures::initialized_); |
51 return ExternalReference(&CpuFeatures::supported_); | 51 return ExternalReference(&CpuFeatures::supported_); |
52 } | 52 } |
53 | 53 |
54 | 54 |
55 void CpuFeatures::Probe() { | 55 void CpuFeatures::Probe() { |
56 ASSERT(supported_ == CpuFeatures::kDefaultCpuFeatures); | 56 ASSERT(supported_ == CpuFeatures::kDefaultCpuFeatures); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 // CPUID not supported. Clear the supported features in rax. | 101 // CPUID not supported. Clear the supported features in rax. |
102 __ xor_(rax, rax); | 102 __ xor_(rax, rax); |
103 __ jmp(&done); | 103 __ jmp(&done); |
104 | 104 |
105 // Invoke CPUID with 1 in eax to get feature information in | 105 // Invoke CPUID with 1 in eax to get feature information in |
106 // ecx:edx. Temporarily enable CPUID support because we know it's | 106 // ecx:edx. Temporarily enable CPUID support because we know it's |
107 // safe here. | 107 // safe here. |
108 __ bind(&cpuid); | 108 __ bind(&cpuid); |
109 __ movl(rax, Immediate(1)); | 109 __ movl(rax, Immediate(1)); |
110 supported_ = kDefaultCpuFeatures | (1 << CPUID); | 110 supported_ = kDefaultCpuFeatures | (1 << CPUID); |
111 { Scope fscope(CPUID); | 111 { CpuFeatureScope fscope(&assm, CPUID); |
112 __ cpuid(); | 112 __ cpuid(); |
113 // Move the result from ecx:edx to rdi. | 113 // Move the result from ecx:edx to rdi. |
114 __ movl(rdi, rdx); // Zero-extended to 64 bits. | 114 __ movl(rdi, rdx); // Zero-extended to 64 bits. |
115 __ shl(rcx, Immediate(32)); | 115 __ shl(rcx, Immediate(32)); |
116 __ or_(rdi, rcx); | 116 __ or_(rdi, rcx); |
117 | 117 |
118 // Get the sahf supported flag, from CPUID(0x80000001) | 118 // Get the sahf supported flag, from CPUID(0x80000001) |
119 __ movq(rax, 0x80000001, RelocInfo::NONE64); | 119 __ movq(rax, 0x80000001, RelocInfo::NONE64); |
120 __ cpuid(); | 120 __ cpuid(); |
121 } | 121 } |
(...skipping 14 matching lines...) Expand all Loading... |
136 __ pop(rbx); | 136 __ pop(rbx); |
137 __ pop(rcx); | 137 __ pop(rcx); |
138 __ pop(rdi); | 138 __ pop(rdi); |
139 __ popfq(); | 139 __ popfq(); |
140 __ pop(rbp); | 140 __ pop(rbp); |
141 __ ret(0); | 141 __ ret(0); |
142 #undef __ | 142 #undef __ |
143 | 143 |
144 typedef uint64_t (*F0)(); | 144 typedef uint64_t (*F0)(); |
145 F0 probe = FUNCTION_CAST<F0>(reinterpret_cast<Address>(memory->address())); | 145 F0 probe = FUNCTION_CAST<F0>(reinterpret_cast<Address>(memory->address())); |
146 supported_ = probe(); | 146 |
147 found_by_runtime_probing_ = supported_; | 147 uint64_t probed_features = probe(); |
148 found_by_runtime_probing_ &= ~kDefaultCpuFeatures; | 148 uint64_t platform_features = OS::CpuFeaturesImpliedByPlatform(); |
149 uint64_t os_guarantees = OS::CpuFeaturesImpliedByPlatform(); | 149 supported_ = probed_features | platform_features; |
150 supported_ |= os_guarantees; | 150 found_by_runtime_probing_only_ |
151 found_by_runtime_probing_ &= ~os_guarantees; | 151 = probed_features & ~kDefaultCpuFeatures & ~platform_features; |
| 152 |
152 // SSE2 and CMOV must be available on an X64 CPU. | 153 // SSE2 and CMOV must be available on an X64 CPU. |
153 ASSERT(IsSupported(CPUID)); | 154 ASSERT(IsSupported(CPUID)); |
154 ASSERT(IsSupported(SSE2)); | 155 ASSERT(IsSupported(SSE2)); |
155 ASSERT(IsSupported(CMOV)); | 156 ASSERT(IsSupported(CMOV)); |
156 | 157 |
157 delete memory; | 158 delete memory; |
158 } | 159 } |
159 | 160 |
160 | 161 |
161 // ----------------------------------------------------------------------------- | 162 // ----------------------------------------------------------------------------- |
(...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
971 | 972 |
972 void Assembler::cmpb_al(Immediate imm8) { | 973 void Assembler::cmpb_al(Immediate imm8) { |
973 ASSERT(is_int8(imm8.value_) || is_uint8(imm8.value_)); | 974 ASSERT(is_int8(imm8.value_) || is_uint8(imm8.value_)); |
974 EnsureSpace ensure_space(this); | 975 EnsureSpace ensure_space(this); |
975 emit(0x3c); | 976 emit(0x3c); |
976 emit(imm8.value_); | 977 emit(imm8.value_); |
977 } | 978 } |
978 | 979 |
979 | 980 |
980 void Assembler::cpuid() { | 981 void Assembler::cpuid() { |
981 ASSERT(CpuFeatures::IsEnabled(CPUID)); | 982 ASSERT(IsEnabled(CPUID)); |
982 EnsureSpace ensure_space(this); | 983 EnsureSpace ensure_space(this); |
983 emit(0x0F); | 984 emit(0x0F); |
984 emit(0xA2); | 985 emit(0xA2); |
985 } | 986 } |
986 | 987 |
987 | 988 |
988 void Assembler::cqo() { | 989 void Assembler::cqo() { |
989 EnsureSpace ensure_space(this); | 990 EnsureSpace ensure_space(this); |
990 emit_rex_64(); | 991 emit_rex_64(); |
991 emit(0x99); | 992 emit(0x99); |
(...skipping 1219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2211 | 2212 |
2212 void Assembler::fistp_s(const Operand& adr) { | 2213 void Assembler::fistp_s(const Operand& adr) { |
2213 EnsureSpace ensure_space(this); | 2214 EnsureSpace ensure_space(this); |
2214 emit_optional_rex_32(adr); | 2215 emit_optional_rex_32(adr); |
2215 emit(0xDB); | 2216 emit(0xDB); |
2216 emit_operand(3, adr); | 2217 emit_operand(3, adr); |
2217 } | 2218 } |
2218 | 2219 |
2219 | 2220 |
2220 void Assembler::fisttp_s(const Operand& adr) { | 2221 void Assembler::fisttp_s(const Operand& adr) { |
2221 ASSERT(CpuFeatures::IsEnabled(SSE3)); | 2222 ASSERT(IsEnabled(SSE3)); |
2222 EnsureSpace ensure_space(this); | 2223 EnsureSpace ensure_space(this); |
2223 emit_optional_rex_32(adr); | 2224 emit_optional_rex_32(adr); |
2224 emit(0xDB); | 2225 emit(0xDB); |
2225 emit_operand(1, adr); | 2226 emit_operand(1, adr); |
2226 } | 2227 } |
2227 | 2228 |
2228 | 2229 |
2229 void Assembler::fisttp_d(const Operand& adr) { | 2230 void Assembler::fisttp_d(const Operand& adr) { |
2230 ASSERT(CpuFeatures::IsEnabled(SSE3)); | 2231 ASSERT(IsEnabled(SSE3)); |
2231 EnsureSpace ensure_space(this); | 2232 EnsureSpace ensure_space(this); |
2232 emit_optional_rex_32(adr); | 2233 emit_optional_rex_32(adr); |
2233 emit(0xDD); | 2234 emit(0xDD); |
2234 emit_operand(1, adr); | 2235 emit_operand(1, adr); |
2235 } | 2236 } |
2236 | 2237 |
2237 | 2238 |
2238 void Assembler::fist_s(const Operand& adr) { | 2239 void Assembler::fist_s(const Operand& adr) { |
2239 EnsureSpace ensure_space(this); | 2240 EnsureSpace ensure_space(this); |
2240 emit_optional_rex_32(adr); | 2241 emit_optional_rex_32(adr); |
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2936 emit(0x66); | 2937 emit(0x66); |
2937 emit_optional_rex_32(dst, src); | 2938 emit_optional_rex_32(dst, src); |
2938 emit(0x0f); | 2939 emit(0x0f); |
2939 emit(0x2e); | 2940 emit(0x2e); |
2940 emit_sse_operand(dst, src); | 2941 emit_sse_operand(dst, src); |
2941 } | 2942 } |
2942 | 2943 |
2943 | 2944 |
2944 void Assembler::roundsd(XMMRegister dst, XMMRegister src, | 2945 void Assembler::roundsd(XMMRegister dst, XMMRegister src, |
2945 Assembler::RoundingMode mode) { | 2946 Assembler::RoundingMode mode) { |
2946 ASSERT(CpuFeatures::IsEnabled(SSE4_1)); | 2947 ASSERT(IsEnabled(SSE4_1)); |
2947 EnsureSpace ensure_space(this); | 2948 EnsureSpace ensure_space(this); |
2948 emit(0x66); | 2949 emit(0x66); |
2949 emit_optional_rex_32(dst, src); | 2950 emit_optional_rex_32(dst, src); |
2950 emit(0x0f); | 2951 emit(0x0f); |
2951 emit(0x3a); | 2952 emit(0x3a); |
2952 emit(0x0b); | 2953 emit(0x0b); |
2953 emit_sse_operand(dst, src); | 2954 emit_sse_operand(dst, src); |
2954 // Mask precision exeption. | 2955 // Mask precision exeption. |
2955 emit(static_cast<byte>(mode) | 0x8); | 2956 emit(static_cast<byte>(mode) | 0x8); |
2956 } | 2957 } |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3055 bool RelocInfo::IsCodedSpecially() { | 3056 bool RelocInfo::IsCodedSpecially() { |
3056 // The deserializer needs to know whether a pointer is specially coded. Being | 3057 // The deserializer needs to know whether a pointer is specially coded. Being |
3057 // specially coded on x64 means that it is a relative 32 bit address, as used | 3058 // specially coded on x64 means that it is a relative 32 bit address, as used |
3058 // by branch instructions. | 3059 // by branch instructions. |
3059 return (1 << rmode_) & kApplyMask; | 3060 return (1 << rmode_) & kApplyMask; |
3060 } | 3061 } |
3061 | 3062 |
3062 } } // namespace v8::internal | 3063 } } // namespace v8::internal |
3063 | 3064 |
3064 #endif // V8_TARGET_ARCH_X64 | 3065 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |