OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_X64 | 7 #if V8_TARGET_ARCH_X64 |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/macro-assembler.h" | 10 #include "src/macro-assembler.h" |
11 #include "src/serialize.h" | 11 #include "src/serialize.h" |
12 | 12 |
13 namespace v8 { | 13 namespace v8 { |
14 namespace internal { | 14 namespace internal { |
15 | 15 |
16 // ----------------------------------------------------------------------------- | 16 // ----------------------------------------------------------------------------- |
17 // Implementation of CpuFeatures | 17 // Implementation of CpuFeatures |
18 | 18 |
19 void CpuFeatures::ProbeImpl(bool cross_compile) { | 19 void CpuFeatures::ProbeImpl(bool cross_compile) { |
20 base::CPU cpu; | 20 base::CPU cpu; |
21 CHECK(cpu.has_sse2()); // SSE2 support is mandatory. | 21 CHECK(cpu.has_sse2()); // SSE2 support is mandatory. |
22 CHECK(cpu.has_cmov()); // CMOV support is mandatory. | 22 CHECK(cpu.has_cmov()); // CMOV support is mandatory. |
23 | 23 |
24 // Only use statically determined features for cross compile (snapshot). | 24 // Only use statically determined features for cross compile (snapshot). |
25 if (cross_compile) return; | 25 if (cross_compile) return; |
26 | 26 |
27 if (cpu.has_sse41() && FLAG_enable_sse4_1) supported_ |= 1u << SSE4_1; | 27 if (cpu.has_sse41() && FLAG_enable_sse4_1) supported_ |= 1u << SSE4_1; |
28 if (cpu.has_sse3() && FLAG_enable_sse3) supported_ |= 1u << SSE3; | 28 if (cpu.has_sse3() && FLAG_enable_sse3) supported_ |= 1u << SSE3; |
29 // SAHF is not generally available in long mode. | 29 // SAHF is not generally available in long mode. |
30 if (cpu.has_sahf() && FLAG_enable_sahf) supported_|= 1u << SAHF; | 30 if (cpu.has_sahf() && FLAG_enable_sahf) supported_ |= 1u << SAHF; |
| 31 if (cpu.has_avx() && FLAG_enable_avx) supported_ |= 1u << AVX; |
| 32 if (cpu.has_fma3() && FLAG_enable_fma3) supported_ |= 1u << FMA3; |
31 } | 33 } |
32 | 34 |
33 | 35 |
34 void CpuFeatures::PrintTarget() { } | 36 void CpuFeatures::PrintTarget() { } |
35 void CpuFeatures::PrintFeatures() { } | 37 void CpuFeatures::PrintFeatures() { |
| 38 printf("SSE3=%d SSE4_1=%d SAHF=%d AVX=%d FMA3=%d\n", |
| 39 CpuFeatures::IsSupported(SSE3), CpuFeatures::IsSupported(SSE4_1), |
| 40 CpuFeatures::IsSupported(SAHF), CpuFeatures::IsSupported(AVX), |
| 41 CpuFeatures::IsSupported(FMA3)); |
| 42 } |
36 | 43 |
37 | 44 |
38 // ----------------------------------------------------------------------------- | 45 // ----------------------------------------------------------------------------- |
39 // Implementation of RelocInfo | 46 // Implementation of RelocInfo |
40 | 47 |
41 // Patch the code at the current PC with a call to the target address. | 48 // Patch the code at the current PC with a call to the target address. |
42 // Additional guard int3 instructions can be added if required. | 49 // Additional guard int3 instructions can be added if required. |
43 void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) { | 50 void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) { |
44 int code_size = Assembler::kCallSequenceLength + guard_bytes; | 51 int code_size = Assembler::kCallSequenceLength + guard_bytes; |
45 | 52 |
(...skipping 2585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2631 } else { | 2638 } else { |
2632 emit(0x66); | 2639 emit(0x66); |
2633 emit_optional_rex_32(dst, src); | 2640 emit_optional_rex_32(dst, src); |
2634 emit(0x0F); | 2641 emit(0x0F); |
2635 emit(0x28); | 2642 emit(0x28); |
2636 emit_sse_operand(dst, src); | 2643 emit_sse_operand(dst, src); |
2637 } | 2644 } |
2638 } | 2645 } |
2639 | 2646 |
2640 | 2647 |
| 2648 void Assembler::addss(XMMRegister dst, XMMRegister src) { |
| 2649 EnsureSpace ensure_space(this); |
| 2650 emit(0xF3); |
| 2651 emit_optional_rex_32(dst, src); |
| 2652 emit(0x0F); |
| 2653 emit(0x58); |
| 2654 emit_sse_operand(dst, src); |
| 2655 } |
| 2656 |
| 2657 |
| 2658 void Assembler::addss(XMMRegister dst, const Operand& src) { |
| 2659 EnsureSpace ensure_space(this); |
| 2660 emit(0xF3); |
| 2661 emit_optional_rex_32(dst, src); |
| 2662 emit(0x0F); |
| 2663 emit(0x58); |
| 2664 emit_sse_operand(dst, src); |
| 2665 } |
| 2666 |
| 2667 |
| 2668 void Assembler::subss(XMMRegister dst, XMMRegister src) { |
| 2669 EnsureSpace ensure_space(this); |
| 2670 emit(0xF3); |
| 2671 emit_optional_rex_32(dst, src); |
| 2672 emit(0x0F); |
| 2673 emit(0x5C); |
| 2674 emit_sse_operand(dst, src); |
| 2675 } |
| 2676 |
| 2677 |
| 2678 void Assembler::subss(XMMRegister dst, const Operand& src) { |
| 2679 EnsureSpace ensure_space(this); |
| 2680 emit(0xF3); |
| 2681 emit_optional_rex_32(dst, src); |
| 2682 emit(0x0F); |
| 2683 emit(0x5C); |
| 2684 emit_sse_operand(dst, src); |
| 2685 } |
| 2686 |
| 2687 |
| 2688 void Assembler::mulss(XMMRegister dst, XMMRegister src) { |
| 2689 EnsureSpace ensure_space(this); |
| 2690 emit(0xF3); |
| 2691 emit_optional_rex_32(dst, src); |
| 2692 emit(0x0F); |
| 2693 emit(0x59); |
| 2694 emit_sse_operand(dst, src); |
| 2695 } |
| 2696 |
| 2697 |
| 2698 void Assembler::mulss(XMMRegister dst, const Operand& src) { |
| 2699 EnsureSpace ensure_space(this); |
| 2700 emit(0xF3); |
| 2701 emit_optional_rex_32(dst, src); |
| 2702 emit(0x0F); |
| 2703 emit(0x59); |
| 2704 emit_sse_operand(dst, src); |
| 2705 } |
| 2706 |
| 2707 |
| 2708 void Assembler::divss(XMMRegister dst, XMMRegister src) { |
| 2709 EnsureSpace ensure_space(this); |
| 2710 emit(0xF3); |
| 2711 emit_optional_rex_32(dst, src); |
| 2712 emit(0x0F); |
| 2713 emit(0x5E); |
| 2714 emit_sse_operand(dst, src); |
| 2715 } |
| 2716 |
| 2717 |
| 2718 void Assembler::divss(XMMRegister dst, const Operand& src) { |
| 2719 EnsureSpace ensure_space(this); |
| 2720 emit(0xF3); |
| 2721 emit_optional_rex_32(dst, src); |
| 2722 emit(0x0F); |
| 2723 emit(0x5E); |
| 2724 emit_sse_operand(dst, src); |
| 2725 } |
| 2726 |
| 2727 |
| 2728 void Assembler::ucomiss(XMMRegister dst, XMMRegister src) { |
| 2729 EnsureSpace ensure_space(this); |
| 2730 emit_optional_rex_32(dst, src); |
| 2731 emit(0x0f); |
| 2732 emit(0x2e); |
| 2733 emit_sse_operand(dst, src); |
| 2734 } |
| 2735 |
| 2736 |
| 2737 void Assembler::ucomiss(XMMRegister dst, const Operand& src) { |
| 2738 EnsureSpace ensure_space(this); |
| 2739 emit_optional_rex_32(dst, src); |
| 2740 emit(0x0f); |
| 2741 emit(0x2e); |
| 2742 emit_sse_operand(dst, src); |
| 2743 } |
| 2744 |
| 2745 |
2641 void Assembler::movss(XMMRegister dst, const Operand& src) { | 2746 void Assembler::movss(XMMRegister dst, const Operand& src) { |
2642 EnsureSpace ensure_space(this); | 2747 EnsureSpace ensure_space(this); |
2643 emit(0xF3); // single | 2748 emit(0xF3); // single |
2644 emit_optional_rex_32(dst, src); | 2749 emit_optional_rex_32(dst, src); |
2645 emit(0x0F); | 2750 emit(0x0F); |
2646 emit(0x10); // load | 2751 emit(0x10); // load |
2647 emit_sse_operand(dst, src); | 2752 emit_sse_operand(dst, src); |
2648 } | 2753 } |
2649 | 2754 |
2650 | 2755 |
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3070 void Assembler::pcmpeqd(XMMRegister dst, XMMRegister src) { | 3175 void Assembler::pcmpeqd(XMMRegister dst, XMMRegister src) { |
3071 EnsureSpace ensure_space(this); | 3176 EnsureSpace ensure_space(this); |
3072 emit(0x66); | 3177 emit(0x66); |
3073 emit_optional_rex_32(dst, src); | 3178 emit_optional_rex_32(dst, src); |
3074 emit(0x0F); | 3179 emit(0x0F); |
3075 emit(0x76); | 3180 emit(0x76); |
3076 emit_sse_operand(dst, src); | 3181 emit_sse_operand(dst, src); |
3077 } | 3182 } |
3078 | 3183 |
3079 | 3184 |
| 3185 // byte 1 of 3-byte VEX |
| 3186 void Assembler::emit_vex3_byte1(XMMRegister reg, XMMRegister rm, byte m) { |
| 3187 DCHECK(1 <= m && m <= 3); |
| 3188 byte rxb = ~((reg.high_bit() << 2) | rm.high_bit()) << 5; |
| 3189 emit(rxb | m); |
| 3190 } |
| 3191 |
| 3192 |
| 3193 // byte 1 of 3-byte VEX |
| 3194 void Assembler::emit_vex3_byte1(XMMRegister reg, const Operand& rm, byte m) { |
| 3195 DCHECK(1 <= m && m <= 3); |
| 3196 byte rxb = ~((reg.high_bit() << 2) | rm.rex_) << 5; |
| 3197 emit(rxb | m); |
| 3198 } |
| 3199 |
| 3200 |
| 3201 // byte 1 of 2-byte VEX |
| 3202 void Assembler::emit_vex2_byte1(XMMRegister reg, XMMRegister v, byte lpp) { |
| 3203 DCHECK(lpp <= 3); |
| 3204 byte rv = ~((reg.high_bit() << 4) | v.code()) << 3; |
| 3205 emit(rv | lpp); |
| 3206 } |
| 3207 |
| 3208 |
| 3209 // byte 2 of 3-byte VEX |
| 3210 void Assembler::emit_vex3_byte2(byte w, XMMRegister v, byte lpp) { |
| 3211 DCHECK(w <= 1); |
| 3212 DCHECK(lpp <= 3); |
| 3213 emit((w << 7) | ((~v.code() & 0xf) << 3) | lpp); |
| 3214 } |
| 3215 |
| 3216 |
| 3217 void Assembler::vfmasd(byte op, XMMRegister dst, XMMRegister src1, |
| 3218 XMMRegister src2) { |
| 3219 DCHECK(IsEnabled(FMA3)); |
| 3220 EnsureSpace ensure_space(this); |
| 3221 emit_vex3_byte0(); |
| 3222 emit_vex3_byte1(dst, src2, 0x02); |
| 3223 emit_vex3_byte2(0x1, src1, 0x01); |
| 3224 emit(op); |
| 3225 emit_sse_operand(dst, src2); |
| 3226 } |
| 3227 |
| 3228 |
| 3229 void Assembler::vfmasd(byte op, XMMRegister dst, XMMRegister src1, |
| 3230 const Operand& src2) { |
| 3231 DCHECK(IsEnabled(FMA3)); |
| 3232 EnsureSpace ensure_space(this); |
| 3233 emit_vex3_byte0(); |
| 3234 emit_vex3_byte1(dst, src2, 0x02); |
| 3235 emit_vex3_byte2(0x1, src1, 0x01); |
| 3236 emit(op); |
| 3237 emit_sse_operand(dst, src2); |
| 3238 } |
| 3239 |
| 3240 |
| 3241 void Assembler::vfmass(byte op, XMMRegister dst, XMMRegister src1, |
| 3242 XMMRegister src2) { |
| 3243 DCHECK(IsEnabled(FMA3)); |
| 3244 EnsureSpace ensure_space(this); |
| 3245 emit_vex3_byte0(); |
| 3246 emit_vex3_byte1(dst, src2, 0x02); |
| 3247 emit_vex3_byte2(0x0, src1, 0x01); |
| 3248 emit(op); |
| 3249 emit_sse_operand(dst, src2); |
| 3250 } |
| 3251 |
| 3252 |
| 3253 void Assembler::vfmass(byte op, XMMRegister dst, XMMRegister src1, |
| 3254 const Operand& src2) { |
| 3255 DCHECK(IsEnabled(FMA3)); |
| 3256 EnsureSpace ensure_space(this); |
| 3257 emit_vex3_byte0(); |
| 3258 emit_vex3_byte1(dst, src2, 0x02); |
| 3259 emit_vex3_byte2(0x0, src1, 0x01); |
| 3260 emit(op); |
| 3261 emit_sse_operand(dst, src2); |
| 3262 } |
| 3263 |
| 3264 |
3080 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) { | 3265 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) { |
3081 Register ireg = { reg.code() }; | 3266 Register ireg = { reg.code() }; |
3082 emit_operand(ireg, adr); | 3267 emit_operand(ireg, adr); |
3083 } | 3268 } |
3084 | 3269 |
3085 | 3270 |
3086 void Assembler::emit_sse_operand(Register reg, const Operand& adr) { | 3271 void Assembler::emit_sse_operand(Register reg, const Operand& adr) { |
3087 Register ireg = {reg.code()}; | 3272 Register ireg = {reg.code()}; |
3088 emit_operand(ireg, adr); | 3273 emit_operand(ireg, adr); |
3089 } | 3274 } |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3184 | 3369 |
3185 | 3370 |
3186 bool RelocInfo::IsInConstantPool() { | 3371 bool RelocInfo::IsInConstantPool() { |
3187 return false; | 3372 return false; |
3188 } | 3373 } |
3189 | 3374 |
3190 | 3375 |
3191 } } // namespace v8::internal | 3376 } } // namespace v8::internal |
3192 | 3377 |
3193 #endif // V8_TARGET_ARCH_X64 | 3378 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |