Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(30)

Side by Side Diff: src/compiler/ia32/code-generator-ia32.cc

Issue 1584663007: [turbofan] Implement rounding of floats on x64 and ia32 without sse4.1. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/compiler/ia32/instruction-selector-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | src/compiler/ia32/instruction-selector-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698