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/x64/assembler-x64.h" | 5 #include "src/x64/assembler-x64.h" |
6 | 6 |
7 #include <cstring> | 7 #include <cstring> |
8 | 8 |
9 #if V8_TARGET_ARCH_X64 | 9 #if V8_TARGET_ARCH_X64 |
10 | 10 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 // SAHF is not generally available in long mode. | 83 // SAHF is not generally available in long mode. |
84 if (cpu.has_sahf() && FLAG_enable_sahf) supported_ |= 1u << SAHF; | 84 if (cpu.has_sahf() && FLAG_enable_sahf) supported_ |= 1u << SAHF; |
85 if (cpu.has_avx() && FLAG_enable_avx && cpu.has_osxsave() && | 85 if (cpu.has_avx() && FLAG_enable_avx && cpu.has_osxsave() && |
86 OSHasAVXSupport()) { | 86 OSHasAVXSupport()) { |
87 supported_ |= 1u << AVX; | 87 supported_ |= 1u << AVX; |
88 } | 88 } |
89 if (cpu.has_fma3() && FLAG_enable_fma3 && cpu.has_osxsave() && | 89 if (cpu.has_fma3() && FLAG_enable_fma3 && cpu.has_osxsave() && |
90 OSHasAVXSupport()) { | 90 OSHasAVXSupport()) { |
91 supported_ |= 1u << FMA3; | 91 supported_ |= 1u << FMA3; |
92 } | 92 } |
| 93 if (cpu.has_bmi1() && FLAG_enable_bmi1) supported_ |= 1u << BMI1; |
| 94 if (cpu.has_bmi2() && FLAG_enable_bmi2) supported_ |= 1u << BMI2; |
| 95 if (cpu.has_lzcnt() && FLAG_enable_lzcnt) supported_ |= 1u << LZCNT; |
| 96 if (cpu.has_popcnt() && FLAG_enable_popcnt) supported_ |= 1u << POPCNT; |
93 if (strcmp(FLAG_mcpu, "auto") == 0) { | 97 if (strcmp(FLAG_mcpu, "auto") == 0) { |
94 if (cpu.is_atom()) supported_ |= 1u << ATOM; | 98 if (cpu.is_atom()) supported_ |= 1u << ATOM; |
95 } else if (strcmp(FLAG_mcpu, "atom") == 0) { | 99 } else if (strcmp(FLAG_mcpu, "atom") == 0) { |
96 supported_ |= 1u << ATOM; | 100 supported_ |= 1u << ATOM; |
97 } | 101 } |
98 } | 102 } |
99 | 103 |
100 | 104 |
101 void CpuFeatures::PrintTarget() { } | 105 void CpuFeatures::PrintTarget() { } |
102 void CpuFeatures::PrintFeatures() { | 106 void CpuFeatures::PrintFeatures() { |
103 printf("SSE3=%d SSE4_1=%d SAHF=%d AVX=%d FMA3=%d ATOM=%d\n", | 107 printf( |
104 CpuFeatures::IsSupported(SSE3), CpuFeatures::IsSupported(SSE4_1), | 108 "SSE3=%d SSE4_1=%d SAHF=%d AVX=%d FMA3=%d BMI1=%d BMI2=%d LZCNT=%d " |
105 CpuFeatures::IsSupported(SAHF), CpuFeatures::IsSupported(AVX), | 109 "POPCNT=%d ATOM=%d\n", |
106 CpuFeatures::IsSupported(FMA3), CpuFeatures::IsSupported(ATOM)); | 110 CpuFeatures::IsSupported(SSE3), CpuFeatures::IsSupported(SSE4_1), |
| 111 CpuFeatures::IsSupported(SAHF), CpuFeatures::IsSupported(AVX), |
| 112 CpuFeatures::IsSupported(FMA3), CpuFeatures::IsSupported(BMI1), |
| 113 CpuFeatures::IsSupported(BMI2), CpuFeatures::IsSupported(LZCNT), |
| 114 CpuFeatures::IsSupported(POPCNT), CpuFeatures::IsSupported(ATOM)); |
107 } | 115 } |
108 | 116 |
109 | 117 |
110 // ----------------------------------------------------------------------------- | 118 // ----------------------------------------------------------------------------- |
111 // Register constants. | 119 // Register constants. |
112 | 120 |
113 const int | 121 const int |
114 Register::kRegisterCodeByAllocationIndex[kMaxNumAllocatableRegisters] = { | 122 Register::kRegisterCodeByAllocationIndex[kMaxNumAllocatableRegisters] = { |
115 // rax, rbx, rdx, rcx, rsi, rdi, r8, r9, r11, r12, r14, r15 | 123 // rax, rbx, rdx, rcx, rsi, rdi, r8, r9, r11, r12, r14, r15 |
116 0, 3, 2, 1, 6, 7, 8, 9, 11, 12, 14, 15 | 124 0, 3, 2, 1, 6, 7, 8, 9, 11, 12, 14, 15 |
(...skipping 3416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3533 void Assembler::vss(byte op, XMMRegister dst, XMMRegister src1, | 3541 void Assembler::vss(byte op, XMMRegister dst, XMMRegister src1, |
3534 const Operand& src2) { | 3542 const Operand& src2) { |
3535 DCHECK(IsEnabled(AVX)); | 3543 DCHECK(IsEnabled(AVX)); |
3536 EnsureSpace ensure_space(this); | 3544 EnsureSpace ensure_space(this); |
3537 emit_vex_prefix(dst, src1, src2, kLIG, kF3, k0F, kWIG); | 3545 emit_vex_prefix(dst, src1, src2, kLIG, kF3, k0F, kWIG); |
3538 emit(op); | 3546 emit(op); |
3539 emit_sse_operand(dst, src2); | 3547 emit_sse_operand(dst, src2); |
3540 } | 3548 } |
3541 | 3549 |
3542 | 3550 |
| 3551 void Assembler::bmi1q(byte op, Register reg, Register vreg, Register rm) { |
| 3552 DCHECK(IsEnabled(BMI1)); |
| 3553 EnsureSpace ensure_space(this); |
| 3554 emit_vex_prefix(reg, vreg, rm, kLZ, kNone, k0F38, kW1); |
| 3555 emit(op); |
| 3556 emit_modrm(reg, rm); |
| 3557 } |
| 3558 |
| 3559 |
| 3560 void Assembler::bmi1q(byte op, Register reg, Register vreg, const Operand& rm) { |
| 3561 DCHECK(IsEnabled(BMI1)); |
| 3562 EnsureSpace ensure_space(this); |
| 3563 emit_vex_prefix(reg, vreg, rm, kLZ, kNone, k0F38, kW1); |
| 3564 emit(op); |
| 3565 emit_operand(reg, rm); |
| 3566 } |
| 3567 |
| 3568 |
| 3569 void Assembler::bmi1l(byte op, Register reg, Register vreg, Register rm) { |
| 3570 DCHECK(IsEnabled(BMI1)); |
| 3571 EnsureSpace ensure_space(this); |
| 3572 emit_vex_prefix(reg, vreg, rm, kLZ, kNone, k0F38, kW0); |
| 3573 emit(op); |
| 3574 emit_modrm(reg, rm); |
| 3575 } |
| 3576 |
| 3577 |
| 3578 void Assembler::bmi1l(byte op, Register reg, Register vreg, const Operand& rm) { |
| 3579 DCHECK(IsEnabled(BMI1)); |
| 3580 EnsureSpace ensure_space(this); |
| 3581 emit_vex_prefix(reg, vreg, rm, kLZ, kNone, k0F38, kW0); |
| 3582 emit(op); |
| 3583 emit_operand(reg, rm); |
| 3584 } |
| 3585 |
| 3586 |
| 3587 void Assembler::tzcntq(Register dst, Register src) { |
| 3588 DCHECK(IsEnabled(BMI1)); |
| 3589 EnsureSpace ensure_space(this); |
| 3590 emit(0xF3); |
| 3591 emit_rex_64(dst, src); |
| 3592 emit(0x0F); |
| 3593 emit(0xBC); |
| 3594 emit_modrm(dst, src); |
| 3595 } |
| 3596 |
| 3597 |
| 3598 void Assembler::tzcntq(Register dst, const Operand& src) { |
| 3599 DCHECK(IsEnabled(BMI1)); |
| 3600 EnsureSpace ensure_space(this); |
| 3601 emit(0xF3); |
| 3602 emit_rex_64(dst, src); |
| 3603 emit(0x0F); |
| 3604 emit(0xBC); |
| 3605 emit_operand(dst, src); |
| 3606 } |
| 3607 |
| 3608 |
| 3609 void Assembler::tzcntl(Register dst, Register src) { |
| 3610 DCHECK(IsEnabled(BMI1)); |
| 3611 EnsureSpace ensure_space(this); |
| 3612 emit(0xF3); |
| 3613 emit_optional_rex_32(dst, src); |
| 3614 emit(0x0F); |
| 3615 emit(0xBC); |
| 3616 emit_modrm(dst, src); |
| 3617 } |
| 3618 |
| 3619 |
| 3620 void Assembler::tzcntl(Register dst, const Operand& src) { |
| 3621 DCHECK(IsEnabled(BMI1)); |
| 3622 EnsureSpace ensure_space(this); |
| 3623 emit(0xF3); |
| 3624 emit_optional_rex_32(dst, src); |
| 3625 emit(0x0F); |
| 3626 emit(0xBC); |
| 3627 emit_operand(dst, src); |
| 3628 } |
| 3629 |
| 3630 |
| 3631 void Assembler::lzcntq(Register dst, Register src) { |
| 3632 DCHECK(IsEnabled(LZCNT)); |
| 3633 EnsureSpace ensure_space(this); |
| 3634 emit(0xF3); |
| 3635 emit_rex_64(dst, src); |
| 3636 emit(0x0F); |
| 3637 emit(0xBD); |
| 3638 emit_modrm(dst, src); |
| 3639 } |
| 3640 |
| 3641 |
| 3642 void Assembler::lzcntq(Register dst, const Operand& src) { |
| 3643 DCHECK(IsEnabled(LZCNT)); |
| 3644 EnsureSpace ensure_space(this); |
| 3645 emit(0xF3); |
| 3646 emit_rex_64(dst, src); |
| 3647 emit(0x0F); |
| 3648 emit(0xBD); |
| 3649 emit_operand(dst, src); |
| 3650 } |
| 3651 |
| 3652 |
| 3653 void Assembler::lzcntl(Register dst, Register src) { |
| 3654 DCHECK(IsEnabled(LZCNT)); |
| 3655 EnsureSpace ensure_space(this); |
| 3656 emit(0xF3); |
| 3657 emit_optional_rex_32(dst, src); |
| 3658 emit(0x0F); |
| 3659 emit(0xBD); |
| 3660 emit_modrm(dst, src); |
| 3661 } |
| 3662 |
| 3663 |
| 3664 void Assembler::lzcntl(Register dst, const Operand& src) { |
| 3665 DCHECK(IsEnabled(LZCNT)); |
| 3666 EnsureSpace ensure_space(this); |
| 3667 emit(0xF3); |
| 3668 emit_optional_rex_32(dst, src); |
| 3669 emit(0x0F); |
| 3670 emit(0xBD); |
| 3671 emit_operand(dst, src); |
| 3672 } |
| 3673 |
| 3674 |
| 3675 void Assembler::popcntq(Register dst, Register src) { |
| 3676 DCHECK(IsEnabled(POPCNT)); |
| 3677 EnsureSpace ensure_space(this); |
| 3678 emit(0xF3); |
| 3679 emit_rex_64(dst, src); |
| 3680 emit(0x0F); |
| 3681 emit(0xB8); |
| 3682 emit_modrm(dst, src); |
| 3683 } |
| 3684 |
| 3685 |
| 3686 void Assembler::popcntq(Register dst, const Operand& src) { |
| 3687 DCHECK(IsEnabled(POPCNT)); |
| 3688 EnsureSpace ensure_space(this); |
| 3689 emit(0xF3); |
| 3690 emit_rex_64(dst, src); |
| 3691 emit(0x0F); |
| 3692 emit(0xB8); |
| 3693 emit_operand(dst, src); |
| 3694 } |
| 3695 |
| 3696 |
| 3697 void Assembler::popcntl(Register dst, Register src) { |
| 3698 DCHECK(IsEnabled(POPCNT)); |
| 3699 EnsureSpace ensure_space(this); |
| 3700 emit(0xF3); |
| 3701 emit_optional_rex_32(dst, src); |
| 3702 emit(0x0F); |
| 3703 emit(0xB8); |
| 3704 emit_modrm(dst, src); |
| 3705 } |
| 3706 |
| 3707 |
| 3708 void Assembler::popcntl(Register dst, const Operand& src) { |
| 3709 DCHECK(IsEnabled(POPCNT)); |
| 3710 EnsureSpace ensure_space(this); |
| 3711 emit(0xF3); |
| 3712 emit_optional_rex_32(dst, src); |
| 3713 emit(0x0F); |
| 3714 emit(0xB8); |
| 3715 emit_operand(dst, src); |
| 3716 } |
| 3717 |
| 3718 |
| 3719 void Assembler::bmi2q(SIMDPrefix pp, byte op, Register reg, Register vreg, |
| 3720 Register rm) { |
| 3721 DCHECK(IsEnabled(BMI2)); |
| 3722 EnsureSpace ensure_space(this); |
| 3723 emit_vex_prefix(reg, vreg, rm, kLZ, pp, k0F38, kW1); |
| 3724 emit(op); |
| 3725 emit_modrm(reg, rm); |
| 3726 } |
| 3727 |
| 3728 |
| 3729 void Assembler::bmi2q(SIMDPrefix pp, byte op, Register reg, Register vreg, |
| 3730 const Operand& rm) { |
| 3731 DCHECK(IsEnabled(BMI2)); |
| 3732 EnsureSpace ensure_space(this); |
| 3733 emit_vex_prefix(reg, vreg, rm, kLZ, pp, k0F38, kW1); |
| 3734 emit(op); |
| 3735 emit_operand(reg, rm); |
| 3736 } |
| 3737 |
| 3738 |
| 3739 void Assembler::bmi2l(SIMDPrefix pp, byte op, Register reg, Register vreg, |
| 3740 Register rm) { |
| 3741 DCHECK(IsEnabled(BMI2)); |
| 3742 EnsureSpace ensure_space(this); |
| 3743 emit_vex_prefix(reg, vreg, rm, kLZ, pp, k0F38, kW0); |
| 3744 emit(op); |
| 3745 emit_modrm(reg, rm); |
| 3746 } |
| 3747 |
| 3748 |
| 3749 void Assembler::bmi2l(SIMDPrefix pp, byte op, Register reg, Register vreg, |
| 3750 const Operand& rm) { |
| 3751 DCHECK(IsEnabled(BMI2)); |
| 3752 EnsureSpace ensure_space(this); |
| 3753 emit_vex_prefix(reg, vreg, rm, kLZ, pp, k0F38, kW0); |
| 3754 emit(op); |
| 3755 emit_operand(reg, rm); |
| 3756 } |
| 3757 |
| 3758 |
| 3759 void Assembler::rorxq(Register dst, Register src, byte imm8) { |
| 3760 DCHECK(IsEnabled(BMI2)); |
| 3761 DCHECK(is_uint8(imm8)); |
| 3762 Register vreg = {0}; // VEX.vvvv unused |
| 3763 EnsureSpace ensure_space(this); |
| 3764 emit_vex_prefix(dst, vreg, src, kLZ, kF2, k0F3A, kW1); |
| 3765 emit(0xF0); |
| 3766 emit_modrm(dst, src); |
| 3767 emit(imm8); |
| 3768 } |
| 3769 |
| 3770 |
| 3771 void Assembler::rorxq(Register dst, const Operand& src, byte imm8) { |
| 3772 DCHECK(IsEnabled(BMI2)); |
| 3773 DCHECK(is_uint8(imm8)); |
| 3774 Register vreg = {0}; // VEX.vvvv unused |
| 3775 EnsureSpace ensure_space(this); |
| 3776 emit_vex_prefix(dst, vreg, src, kLZ, kF2, k0F3A, kW1); |
| 3777 emit(0xF0); |
| 3778 emit_operand(dst, src); |
| 3779 emit(imm8); |
| 3780 } |
| 3781 |
| 3782 |
| 3783 void Assembler::rorxl(Register dst, Register src, byte imm8) { |
| 3784 DCHECK(IsEnabled(BMI2)); |
| 3785 DCHECK(is_uint8(imm8)); |
| 3786 Register vreg = {0}; // VEX.vvvv unused |
| 3787 EnsureSpace ensure_space(this); |
| 3788 emit_vex_prefix(dst, vreg, src, kLZ, kF2, k0F3A, kW0); |
| 3789 emit(0xF0); |
| 3790 emit_modrm(dst, src); |
| 3791 emit(imm8); |
| 3792 } |
| 3793 |
| 3794 |
| 3795 void Assembler::rorxl(Register dst, const Operand& src, byte imm8) { |
| 3796 DCHECK(IsEnabled(BMI2)); |
| 3797 DCHECK(is_uint8(imm8)); |
| 3798 Register vreg = {0}; // VEX.vvvv unused |
| 3799 EnsureSpace ensure_space(this); |
| 3800 emit_vex_prefix(dst, vreg, src, kLZ, kF2, k0F3A, kW0); |
| 3801 emit(0xF0); |
| 3802 emit_operand(dst, src); |
| 3803 emit(imm8); |
| 3804 } |
| 3805 |
| 3806 |
3543 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) { | 3807 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) { |
3544 Register ireg = { reg.code() }; | 3808 Register ireg = { reg.code() }; |
3545 emit_operand(ireg, adr); | 3809 emit_operand(ireg, adr); |
3546 } | 3810 } |
3547 | 3811 |
3548 | 3812 |
3549 void Assembler::emit_sse_operand(Register reg, const Operand& adr) { | 3813 void Assembler::emit_sse_operand(Register reg, const Operand& adr) { |
3550 Register ireg = {reg.code()}; | 3814 Register ireg = {reg.code()}; |
3551 emit_operand(ireg, adr); | 3815 emit_operand(ireg, adr); |
3552 } | 3816 } |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3646 | 3910 |
3647 | 3911 |
3648 bool RelocInfo::IsInConstantPool() { | 3912 bool RelocInfo::IsInConstantPool() { |
3649 return false; | 3913 return false; |
3650 } | 3914 } |
3651 | 3915 |
3652 | 3916 |
3653 } } // namespace v8::internal | 3917 } } // namespace v8::internal |
3654 | 3918 |
3655 #endif // V8_TARGET_ARCH_X64 | 3919 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |