OLD | NEW |
---|---|
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 | 6 |
7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
9 #include "src/compiler/gap-resolver.h" | 9 #include "src/compiler/gap-resolver.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
647 break; | 647 break; |
648 } | 648 } |
649 case kSSEFloat32Neg: { | 649 case kSSEFloat32Neg: { |
650 // TODO(bmeurer): Use 128-bit constants. | 650 // TODO(bmeurer): Use 128-bit constants. |
651 __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg); | 651 __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg); |
652 __ psllq(kScratchDoubleReg, 31); | 652 __ psllq(kScratchDoubleReg, 31); |
653 __ xorps(i.OutputDoubleRegister(), kScratchDoubleReg); | 653 __ xorps(i.OutputDoubleRegister(), kScratchDoubleReg); |
654 break; | 654 break; |
655 } | 655 } |
656 case kSSEFloat32Round: { | 656 case kSSEFloat32Round: { |
657 CpuFeatureScope sse_scope(masm(), SSE4_1); | |
658 RoundingMode const mode = | 657 RoundingMode const mode = |
659 static_cast<RoundingMode>(MiscField::decode(instr->opcode())); | 658 static_cast<RoundingMode>(MiscField::decode(instr->opcode())); |
659 if (CpuFeatures::IsSupported(SSE4_1)) { | |
660 CpuFeatureScope sse_scope(masm(), SSE4_1); | |
660 __ roundss(i.OutputDoubleRegister(), i.InputDoubleRegister(0), mode); | 661 __ roundss(i.OutputDoubleRegister(), i.InputDoubleRegister(0), mode); |
662 } else { | |
663 Register kScratchRegister = i.TempRegister(0); | |
titzer
2016/01/18 10:44:28
Don't call this kScratchRegister, it's not a const
ahaas
2016/01/18 15:30:30
Done.
| |
664 | |
665 // We have to store the original rounding mode to restore it later. | |
titzer
2016/01/18 10:44:28
This code sucks so much I think it should go to ma
ahaas
2016/01/18 15:30:30
Done.
| |
666 __ sub(esp, Immediate(kPointerSize * 2)); | |
667 __ stmxcsr(Operand(esp, 0)); | |
668 __ mov(kScratchRegister, Operand(esp, 0)); | |
669 __ and_(kScratchRegister, Immediate(0xffff9fff)); | |
670 __ or_(kScratchRegister, Immediate(mode << 13)); | |
671 __ mov(Operand(esp, kPointerSize), kScratchRegister); | |
672 __ ldmxcsr(Operand(esp, kPointerSize)); | |
673 | |
674 // Convert the input to int32. | |
675 if (instr->InputAt(0)->IsDoubleRegister()) { | |
676 __ cvtss2si(kScratchRegister, i.InputDoubleRegister(0)); | |
titzer
2016/01/18 10:44:28
If you require the input to be in a register, you
ahaas
2016/01/18 15:30:30
Done.
| |
677 } else { | |
678 __ cvtss2si(kScratchRegister, i.InputOperand(0)); | |
679 } | |
680 | |
681 Label out_of_range; | |
682 Label done; | |
683 // Check whether the input is within int32 range. | |
684 __ cmp(kScratchRegister, Immediate(1)); | |
685 __ j(overflow, &out_of_range); | |
686 // The input is within int32 range. We achieve rounding by converting | |
687 // back to float. | |
688 __ cvtsi2ss(i.OutputDoubleRegister(), kScratchRegister); | |
689 __ jmp(&done); | |
690 __ bind(&out_of_range); | |
691 | |
692 // The input value is already an integer number, no rounding necessary. | |
titzer
2016/01/18 10:44:28
If you do a DefineSameAsFirst, you can get rid of
ahaas
2016/01/18 15:30:30
Done.
| |
693 if (instr->InputAt(0)->IsDoubleRegister()) { | |
694 __ movss(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | |
695 } else { | |
696 __ movss(i.OutputDoubleRegister(), i.InputOperand(0)); | |
697 } | |
698 | |
699 __ bind(&done); | |
700 // Restore the original rounding mode. | |
701 __ ldmxcsr(Operand(esp, 0)); | |
702 __ add(esp, Immediate(kPointerSize * 2)); | |
703 } | |
661 break; | 704 break; |
662 } | 705 } |
663 case kSSEFloat64Cmp: | 706 case kSSEFloat64Cmp: |
664 __ ucomisd(i.InputDoubleRegister(0), i.InputOperand(1)); | 707 __ ucomisd(i.InputDoubleRegister(0), i.InputOperand(1)); |
665 break; | 708 break; |
666 case kSSEFloat64Add: | 709 case kSSEFloat64Add: |
667 __ addsd(i.InputDoubleRegister(0), i.InputOperand(1)); | 710 __ addsd(i.InputDoubleRegister(0), i.InputOperand(1)); |
668 break; | 711 break; |
669 case kSSEFloat64Sub: | 712 case kSSEFloat64Sub: |
670 __ subsd(i.InputDoubleRegister(0), i.InputOperand(1)); | 713 __ subsd(i.InputDoubleRegister(0), i.InputOperand(1)); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
720 // TODO(bmeurer): Use 128-bit constants. | 763 // TODO(bmeurer): Use 128-bit constants. |
721 __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg); | 764 __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg); |
722 __ psllq(kScratchDoubleReg, 63); | 765 __ psllq(kScratchDoubleReg, 63); |
723 __ xorpd(i.OutputDoubleRegister(), kScratchDoubleReg); | 766 __ xorpd(i.OutputDoubleRegister(), kScratchDoubleReg); |
724 break; | 767 break; |
725 } | 768 } |
726 case kSSEFloat64Sqrt: | 769 case kSSEFloat64Sqrt: |
727 __ sqrtsd(i.OutputDoubleRegister(), i.InputOperand(0)); | 770 __ sqrtsd(i.OutputDoubleRegister(), i.InputOperand(0)); |
728 break; | 771 break; |
729 case kSSEFloat64Round: { | 772 case kSSEFloat64Round: { |
730 CpuFeatureScope sse_scope(masm(), SSE4_1); | |
731 RoundingMode const mode = | 773 RoundingMode const mode = |
732 static_cast<RoundingMode>(MiscField::decode(instr->opcode())); | 774 static_cast<RoundingMode>(MiscField::decode(instr->opcode())); |
733 __ roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0), mode); | 775 if (CpuFeatures::IsSupported(SSE4_1)) { |
776 CpuFeatureScope sse_scope(masm(), SSE4_1); | |
777 __ roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0), mode); | |
778 } else { | |
779 Register kScratchRegister = i.TempRegister(0); | |
780 | |
781 // We have to store the original rounding mode to restore it later. | |
782 __ sub(esp, Immediate(kPointerSize * 2)); | |
783 __ stmxcsr(Operand(esp, 0)); | |
784 __ mov(kScratchRegister, Operand(esp, 0)); | |
785 __ and_(kScratchRegister, Immediate(0xffff9fff)); | |
786 __ or_(kScratchRegister, Immediate(mode << 13)); | |
787 __ mov(Operand(esp, kPointerSize), kScratchRegister); | |
788 __ ldmxcsr(Operand(esp, kPointerSize)); | |
789 | |
790 // Convert the input to int32. | |
791 if (instr->InputAt(0)->IsDoubleRegister()) { | |
titzer
2016/01/18 10:44:28
Same for this one. Require the input in a register
ahaas
2016/01/18 15:30:30
Done.
| |
792 __ cvtsd2si(kScratchRegister, i.InputDoubleRegister(0)); | |
793 } else { | |
794 __ cvtsd2si(kScratchRegister, i.InputOperand(0)); | |
795 } | |
796 | |
797 Label out_of_range; | |
798 Label done; | |
799 // Check whether the input is within int32 range. | |
800 __ cmp(kScratchRegister, Immediate(1)); | |
801 __ j(overflow, &out_of_range); | |
802 // The input is within int32 range. We achieve rounding by converting | |
803 // back to float. | |
804 __ Cvtsi2sd(i.OutputDoubleRegister(), kScratchRegister); | |
805 __ jmp(&done); | |
806 __ bind(&out_of_range); | |
807 | |
808 if (instr->InputAt(0)->IsDoubleRegister()) { | |
809 __ movsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | |
810 } else { | |
811 __ movsd(i.OutputDoubleRegister(), i.InputOperand(0)); | |
812 } | |
813 | |
814 // If the input is outside [-2^52, 2^52], then the result = input. | |
815 int64_t offset = 1; | |
816 offset <<= 52; | |
817 __ Move(kScratchDoubleReg, static_cast<double>(offset)); | |
818 | |
819 if (instr->InputAt(0)->IsDoubleRegister()) { | |
820 __ ucomisd(kScratchDoubleReg, i.InputDoubleRegister(0)); | |
821 } else { | |
822 __ ucomisd(kScratchDoubleReg, i.InputOperand(0)); | |
823 } | |
824 | |
825 __ j(below_equal, &done); | |
826 | |
827 __ Move(kScratchDoubleReg, static_cast<double>(-offset)); | |
828 | |
829 if (instr->InputAt(0)->IsDoubleRegister()) { | |
830 __ ucomisd(kScratchDoubleReg, i.InputDoubleRegister(0)); | |
831 } else { | |
832 __ ucomisd(kScratchDoubleReg, i.InputOperand(0)); | |
833 } | |
834 __ j(above_equal, &done); | |
835 | |
836 // Positive number have to be handled differently than negative numbers. | |
837 __ xorpd(kScratchDoubleReg, kScratchDoubleReg); | |
838 if (instr->InputAt(0)->IsDoubleRegister()) { | |
839 __ ucomisd(kScratchDoubleReg, i.InputDoubleRegister(0)); | |
840 } else { | |
841 __ ucomisd(kScratchDoubleReg, i.InputOperand(0)); | |
842 } | |
843 | |
844 __ Move(kScratchDoubleReg, static_cast<double>(offset)); | |
845 | |
846 Label below_zero; | |
847 __ j(above, &below_zero); | |
848 | |
849 __ addsd(i.OutputDoubleRegister(), kScratchDoubleReg); | |
850 __ subsd(i.OutputDoubleRegister(), kScratchDoubleReg); | |
851 __ jmp(&done); | |
852 | |
853 __ bind(&below_zero); | |
854 __ subsd(i.OutputDoubleRegister(), kScratchDoubleReg); | |
855 __ addsd(i.OutputDoubleRegister(), kScratchDoubleReg); | |
856 | |
857 __ bind(&done); | |
858 // Restore the original rounding mode. | |
859 __ ldmxcsr(Operand(esp, 0)); | |
860 __ add(esp, Immediate(kPointerSize * 2)); | |
861 } | |
734 break; | 862 break; |
735 } | 863 } |
736 case kSSEFloat32ToFloat64: | 864 case kSSEFloat32ToFloat64: |
737 __ cvtss2sd(i.OutputDoubleRegister(), i.InputOperand(0)); | 865 __ cvtss2sd(i.OutputDoubleRegister(), i.InputOperand(0)); |
738 break; | 866 break; |
739 case kSSEFloat64ToFloat32: | 867 case kSSEFloat64ToFloat32: |
740 __ cvtsd2ss(i.OutputDoubleRegister(), i.InputOperand(0)); | 868 __ cvtsd2ss(i.OutputDoubleRegister(), i.InputOperand(0)); |
741 break; | 869 break; |
742 case kSSEFloat64ToInt32: | 870 case kSSEFloat64ToInt32: |
743 __ cvttsd2si(i.OutputRegister(), i.InputOperand(0)); | 871 __ cvttsd2si(i.OutputRegister(), i.InputOperand(0)); |
(...skipping 944 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1688 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; | 1816 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; |
1689 __ Nop(padding_size); | 1817 __ Nop(padding_size); |
1690 } | 1818 } |
1691 } | 1819 } |
1692 | 1820 |
1693 #undef __ | 1821 #undef __ |
1694 | 1822 |
1695 } // namespace compiler | 1823 } // namespace compiler |
1696 } // namespace internal | 1824 } // namespace internal |
1697 } // namespace v8 | 1825 } // namespace v8 |
OLD | NEW |