Chromium Code Reviews| 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 |