OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
722 scratch2, | 722 scratch2, |
723 scratch3); | 723 scratch3); |
724 __ bind(&done); | 724 __ bind(&done); |
725 } | 725 } |
726 | 726 |
727 | 727 |
728 void FloatingPointHelper::ConvertIntToDouble(MacroAssembler* masm, | 728 void FloatingPointHelper::ConvertIntToDouble(MacroAssembler* masm, |
729 Register int_scratch, | 729 Register int_scratch, |
730 Destination destination, | 730 Destination destination, |
731 DwVfpRegister double_dst, | 731 DwVfpRegister double_dst, |
732 Register dst1, | 732 Register dst_mantissa, |
733 Register dst2, | 733 Register dst_exponent, |
734 Register scratch2, | 734 Register scratch2, |
735 SwVfpRegister single_scratch) { | 735 SwVfpRegister single_scratch) { |
736 ASSERT(!int_scratch.is(scratch2)); | 736 ASSERT(!int_scratch.is(scratch2)); |
737 ASSERT(!int_scratch.is(dst1)); | 737 ASSERT(!int_scratch.is(dst_mantissa)); |
738 ASSERT(!int_scratch.is(dst2)); | 738 ASSERT(!int_scratch.is(dst_exponent)); |
739 | 739 |
740 Label done; | 740 Label done; |
741 | 741 |
742 if (CpuFeatures::IsSupported(VFP2)) { | 742 if (CpuFeatures::IsSupported(VFP2)) { |
743 CpuFeatures::Scope scope(VFP2); | 743 CpuFeatures::Scope scope(VFP2); |
744 __ vmov(single_scratch, int_scratch); | 744 __ vmov(single_scratch, int_scratch); |
745 __ vcvt_f64_s32(double_dst, single_scratch); | 745 __ vcvt_f64_s32(double_dst, single_scratch); |
746 if (destination == kCoreRegisters) { | 746 if (destination == kCoreRegisters) { |
747 __ vmov(dst1, dst2, double_dst); | 747 __ vmov(dst_mantissa, dst_exponent, double_dst); |
748 } | 748 } |
749 } else { | 749 } else { |
750 Label fewer_than_20_useful_bits; | 750 Label fewer_than_20_useful_bits; |
751 // Expected output: | 751 // Expected output: |
752 // | dst2 | dst1 | | 752 // | dst_exponent | dst_mantissa | |
753 // | s | exp | mantissa | | 753 // | s | exp | mantissa | |
754 | 754 |
755 // Check for zero. | 755 // Check for zero. |
756 __ cmp(int_scratch, Operand::Zero()); | 756 __ cmp(int_scratch, Operand::Zero()); |
757 __ mov(dst2, int_scratch); | 757 __ mov(dst_exponent, int_scratch); |
758 __ mov(dst1, int_scratch); | 758 __ mov(dst_mantissa, int_scratch); |
759 __ b(eq, &done); | 759 __ b(eq, &done); |
760 | 760 |
761 // Preload the sign of the value. | 761 // Preload the sign of the value. |
762 __ and_(dst2, int_scratch, Operand(HeapNumber::kSignMask), SetCC); | 762 __ and_(dst_exponent, int_scratch, Operand(HeapNumber::kSignMask), SetCC); |
763 // Get the absolute value of the object (as an unsigned integer). | 763 // Get the absolute value of the object (as an unsigned integer). |
764 __ rsb(int_scratch, int_scratch, Operand::Zero(), SetCC, mi); | 764 __ rsb(int_scratch, int_scratch, Operand::Zero(), SetCC, mi); |
765 | 765 |
766 // Get mantissa[51:20]. | 766 // Get mantissa[51:20]. |
767 | 767 |
768 // Get the position of the first set bit. | 768 // Get the position of the first set bit. |
769 __ CountLeadingZeros(dst1, int_scratch, scratch2); | 769 __ CountLeadingZeros(dst_mantissa, int_scratch, scratch2); |
770 __ rsb(dst1, dst1, Operand(31)); | 770 __ rsb(dst_mantissa, dst_mantissa, Operand(31)); |
771 | 771 |
772 // Set the exponent. | 772 // Set the exponent. |
773 __ add(scratch2, dst1, Operand(HeapNumber::kExponentBias)); | 773 __ add(scratch2, dst_mantissa, Operand(HeapNumber::kExponentBias)); |
774 __ Bfi(dst2, scratch2, scratch2, | 774 __ Bfi(dst_exponent, scratch2, scratch2, |
775 HeapNumber::kExponentShift, HeapNumber::kExponentBits); | 775 HeapNumber::kExponentShift, HeapNumber::kExponentBits); |
776 | 776 |
777 // Clear the first non null bit. | 777 // Clear the first non null bit. |
778 __ mov(scratch2, Operand(1)); | 778 __ mov(scratch2, Operand(1)); |
779 __ bic(int_scratch, int_scratch, Operand(scratch2, LSL, dst1)); | 779 __ bic(int_scratch, int_scratch, Operand(scratch2, LSL, dst_mantissa)); |
780 | 780 |
781 __ cmp(dst1, Operand(HeapNumber::kMantissaBitsInTopWord)); | 781 __ cmp(dst_mantissa, Operand(HeapNumber::kMantissaBitsInTopWord)); |
782 // Get the number of bits to set in the lower part of the mantissa. | 782 // Get the number of bits to set in the lower part of the mantissa. |
783 __ sub(scratch2, dst1, Operand(HeapNumber::kMantissaBitsInTopWord), SetCC); | 783 __ sub(scratch2, dst_mantissa, Operand(HeapNumber::kMantissaBitsInTopWord), |
784 SetCC); | |
784 __ b(mi, &fewer_than_20_useful_bits); | 785 __ b(mi, &fewer_than_20_useful_bits); |
785 // Set the higher 20 bits of the mantissa. | 786 // Set the higher 20 bits of the mantissa. |
786 __ orr(dst2, dst2, Operand(int_scratch, LSR, scratch2)); | 787 __ orr(dst_exponent, dst_exponent, Operand(int_scratch, LSR, scratch2)); |
787 __ rsb(scratch2, scratch2, Operand(32)); | 788 __ rsb(scratch2, scratch2, Operand(32)); |
788 __ mov(dst1, Operand(int_scratch, LSL, scratch2)); | 789 __ mov(dst_mantissa, Operand(int_scratch, LSL, scratch2)); |
789 __ b(&done); | 790 __ b(&done); |
790 | 791 |
791 __ bind(&fewer_than_20_useful_bits); | 792 __ bind(&fewer_than_20_useful_bits); |
792 __ rsb(scratch2, dst1, Operand(HeapNumber::kMantissaBitsInTopWord)); | 793 __ rsb(scratch2, dst_mantissa, Operand(HeapNumber::kMantissaBitsInTopWord)); |
793 __ mov(scratch2, Operand(int_scratch, LSL, scratch2)); | 794 __ mov(scratch2, Operand(int_scratch, LSL, scratch2)); |
794 __ orr(dst2, dst2, scratch2); | 795 __ orr(dst_exponent, dst_exponent, scratch2); |
795 // Set dst1 to 0. | 796 // Set dst1 to 0. |
796 __ mov(dst1, Operand::Zero()); | 797 __ mov(dst_mantissa, Operand::Zero()); |
797 } | 798 } |
798 __ bind(&done); | 799 __ bind(&done); |
799 } | 800 } |
800 | 801 |
801 | 802 |
802 void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm, | 803 void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm, |
803 Register object, | 804 Register object, |
804 Destination destination, | 805 Destination destination, |
805 DwVfpRegister double_dst, | 806 DwVfpRegister double_dst, |
806 DwVfpRegister double_scratch, | 807 DwVfpRegister double_scratch, |
807 Register dst1, | 808 Register dst_mantissa, |
808 Register dst2, | 809 Register dst_exponent, |
809 Register heap_number_map, | 810 Register heap_number_map, |
810 Register scratch1, | 811 Register scratch1, |
811 Register scratch2, | 812 Register scratch2, |
812 SwVfpRegister single_scratch, | 813 SwVfpRegister single_scratch, |
813 Label* not_int32) { | 814 Label* not_int32) { |
814 ASSERT(!scratch1.is(object) && !scratch2.is(object)); | 815 ASSERT(!scratch1.is(object) && !scratch2.is(object)); |
815 ASSERT(!scratch1.is(scratch2)); | 816 ASSERT(!scratch1.is(scratch2)); |
816 ASSERT(!heap_number_map.is(object) && | 817 ASSERT(!heap_number_map.is(object) && |
817 !heap_number_map.is(scratch1) && | 818 !heap_number_map.is(scratch1) && |
818 !heap_number_map.is(scratch2)); | 819 !heap_number_map.is(scratch2)); |
819 | 820 |
820 Label done, obj_is_not_smi; | 821 Label done, obj_is_not_smi; |
821 | 822 |
822 __ JumpIfNotSmi(object, &obj_is_not_smi); | 823 __ JumpIfNotSmi(object, &obj_is_not_smi); |
823 __ SmiUntag(scratch1, object); | 824 __ SmiUntag(scratch1, object); |
824 ConvertIntToDouble(masm, scratch1, destination, double_dst, dst1, dst2, | 825 ConvertIntToDouble(masm, scratch1, destination, double_dst, dst_mantissa, |
825 scratch2, single_scratch); | 826 dst_exponent, scratch2, single_scratch); |
826 __ b(&done); | 827 __ b(&done); |
827 | 828 |
828 __ bind(&obj_is_not_smi); | 829 __ bind(&obj_is_not_smi); |
829 __ AssertRootValue(heap_number_map, | 830 __ AssertRootValue(heap_number_map, |
830 Heap::kHeapNumberMapRootIndex, | 831 Heap::kHeapNumberMapRootIndex, |
831 "HeapNumberMap register clobbered."); | 832 "HeapNumberMap register clobbered."); |
832 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_int32); | 833 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_int32); |
833 | 834 |
834 // Load the number. | 835 // Load the number. |
835 if (CpuFeatures::IsSupported(VFP2)) { | 836 if (CpuFeatures::IsSupported(VFP2)) { |
836 CpuFeatures::Scope scope(VFP2); | 837 CpuFeatures::Scope scope(VFP2); |
837 // Load the double value. | 838 // Load the double value. |
838 __ sub(scratch1, object, Operand(kHeapObjectTag)); | 839 __ sub(scratch1, object, Operand(kHeapObjectTag)); |
839 __ vldr(double_dst, scratch1, HeapNumber::kValueOffset); | 840 __ vldr(double_dst, scratch1, HeapNumber::kValueOffset); |
840 | 841 |
841 __ EmitVFPTruncate(kRoundToZero, | 842 __ EmitVFPTruncate(kRoundToZero, |
842 scratch1, | 843 scratch1, |
843 double_dst, | 844 double_dst, |
844 scratch2, | 845 scratch2, |
845 double_scratch, | 846 double_scratch, |
846 kCheckForInexactConversion); | 847 kCheckForInexactConversion); |
847 | 848 |
848 // Jump to not_int32 if the operation did not succeed. | 849 // Jump to not_int32 if the operation did not succeed. |
849 __ b(ne, not_int32); | 850 __ b(ne, not_int32); |
850 | 851 |
851 if (destination == kCoreRegisters) { | 852 if (destination == kCoreRegisters) { |
852 __ vmov(dst1, dst2, double_dst); | 853 __ vmov(dst_mantissa, dst_exponent, double_dst); |
853 } | 854 } |
854 | 855 |
855 } else { | 856 } else { |
856 ASSERT(!scratch1.is(object) && !scratch2.is(object)); | 857 ASSERT(!scratch1.is(object) && !scratch2.is(object)); |
857 // Load the double value in the destination registers.. | 858 // Load the double value in the destination registers. |
858 __ Ldrd(dst1, dst2, FieldMemOperand(object, HeapNumber::kValueOffset)); | 859 bool save_registers = object.is(dst_mantissa) || object.is(dst_exponent); |
860 if (save_registers) { | |
861 // Save both output registers, because the other one probably holds | |
862 // an important value too. | |
863 __ Push(dst_exponent, dst_mantissa); | |
864 } | |
865 __ Ldrd(dst_mantissa, dst_exponent, | |
866 FieldMemOperand(object, HeapNumber::kValueOffset)); | |
859 | 867 |
860 // Check for 0 and -0. | 868 // Check for 0 and -0. |
861 __ bic(scratch1, dst1, Operand(HeapNumber::kSignMask)); | 869 Label zero; |
862 __ orr(scratch1, scratch1, Operand(dst2)); | 870 __ bic(scratch1, dst_exponent, Operand(HeapNumber::kSignMask)); |
Jakob Kummerow
2012/11/15 17:28:42
Bug fix 1: This code cleared the mantissa's sign b
| |
871 __ orr(scratch1, scratch1, Operand(dst_mantissa)); | |
863 __ cmp(scratch1, Operand::Zero()); | 872 __ cmp(scratch1, Operand::Zero()); |
864 __ b(eq, &done); | 873 __ b(eq, &zero); |
865 | 874 |
866 // Check that the value can be exactly represented by a 32-bit integer. | 875 // Check that the value can be exactly represented by a 32-bit integer. |
867 // Jump to not_int32 if that's not the case. | 876 // Jump to not_int32 if that's not the case. |
868 DoubleIs32BitInteger(masm, dst1, dst2, scratch1, scratch2, not_int32); | 877 Label restore_input_and_miss; |
878 DoubleIs32BitInteger(masm, dst_exponent, dst_mantissa, scratch1, scratch2, | |
Jakob Kummerow
2012/11/15 17:28:42
Bug fix 2: This call passed in the exponent/mantis
| |
879 &restore_input_and_miss); | |
869 | 880 |
870 // dst1 and dst2 were trashed. Reload the double value. | 881 // dst_* were trashed. Reload the double value. |
871 __ Ldrd(dst1, dst2, FieldMemOperand(object, HeapNumber::kValueOffset)); | 882 if (save_registers) { |
883 __ Pop(dst_exponent, dst_mantissa); | |
Jakob Kummerow
2012/11/15 17:28:42
Bug fix 3: Restore the "object" register before re
| |
884 } | |
885 __ Ldrd(dst_mantissa, dst_exponent, | |
886 FieldMemOperand(object, HeapNumber::kValueOffset)); | |
887 __ b(&done); | |
888 | |
889 __ bind(&restore_input_and_miss); | |
890 if (save_registers) { | |
891 __ Pop(dst_exponent, dst_mantissa); | |
Jakob Kummerow
2012/11/15 17:28:42
Bug fix 4: Restore original inputs before calling
| |
892 } | |
893 __ b(not_int32); | |
894 | |
895 __ bind(&zero); | |
896 if (save_registers) { | |
897 __ Drop(2); | |
898 } | |
872 } | 899 } |
873 | 900 |
874 __ bind(&done); | 901 __ bind(&done); |
875 } | 902 } |
876 | 903 |
877 | 904 |
878 void FloatingPointHelper::LoadNumberAsInt32(MacroAssembler* masm, | 905 void FloatingPointHelper::LoadNumberAsInt32(MacroAssembler* masm, |
879 Register object, | 906 Register object, |
880 Register dst, | 907 Register dst, |
881 Register heap_number_map, | 908 Register heap_number_map, |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
953 __ b(ne, not_int32); | 980 __ b(ne, not_int32); |
954 // |undefined| is truncated to 0. | 981 // |undefined| is truncated to 0. |
955 __ mov(dst, Operand(Smi::FromInt(0))); | 982 __ mov(dst, Operand(Smi::FromInt(0))); |
956 // Fall through. | 983 // Fall through. |
957 | 984 |
958 __ bind(&done); | 985 __ bind(&done); |
959 } | 986 } |
960 | 987 |
961 | 988 |
962 void FloatingPointHelper::DoubleIs32BitInteger(MacroAssembler* masm, | 989 void FloatingPointHelper::DoubleIs32BitInteger(MacroAssembler* masm, |
963 Register src1, | 990 Register src_exponent, |
964 Register src2, | 991 Register src_mantissa, |
965 Register dst, | 992 Register dst, |
966 Register scratch, | 993 Register scratch, |
967 Label* not_int32) { | 994 Label* not_int32) { |
968 // Get exponent alone in scratch. | 995 // Get exponent alone in scratch. |
969 __ Ubfx(scratch, | 996 __ Ubfx(scratch, |
970 src1, | 997 src_exponent, |
971 HeapNumber::kExponentShift, | 998 HeapNumber::kExponentShift, |
972 HeapNumber::kExponentBits); | 999 HeapNumber::kExponentBits); |
973 | 1000 |
974 // Substract the bias from the exponent. | 1001 // Substract the bias from the exponent. |
975 __ sub(scratch, scratch, Operand(HeapNumber::kExponentBias), SetCC); | 1002 __ sub(scratch, scratch, Operand(HeapNumber::kExponentBias), SetCC); |
976 | 1003 |
977 // src1: higher (exponent) part of the double value. | 1004 // src1: higher (exponent) part of the double value. |
978 // src2: lower (mantissa) part of the double value. | 1005 // src2: lower (mantissa) part of the double value. |
979 // scratch: unbiased exponent. | 1006 // scratch: unbiased exponent. |
980 | 1007 |
981 // Fast cases. Check for obvious non 32-bit integer values. | 1008 // Fast cases. Check for obvious non 32-bit integer values. |
982 // Negative exponent cannot yield 32-bit integers. | 1009 // Negative exponent cannot yield 32-bit integers. |
983 __ b(mi, not_int32); | 1010 __ b(mi, not_int32); |
984 // Exponent greater than 31 cannot yield 32-bit integers. | 1011 // Exponent greater than 31 cannot yield 32-bit integers. |
985 // Also, a positive value with an exponent equal to 31 is outside of the | 1012 // Also, a positive value with an exponent equal to 31 is outside of the |
986 // signed 32-bit integer range. | 1013 // signed 32-bit integer range. |
987 // Another way to put it is that if (exponent - signbit) > 30 then the | 1014 // Another way to put it is that if (exponent - signbit) > 30 then the |
988 // number cannot be represented as an int32. | 1015 // number cannot be represented as an int32. |
989 Register tmp = dst; | 1016 Register tmp = dst; |
990 __ sub(tmp, scratch, Operand(src1, LSR, 31)); | 1017 __ sub(tmp, scratch, Operand(src_exponent, LSR, 31)); |
991 __ cmp(tmp, Operand(30)); | 1018 __ cmp(tmp, Operand(30)); |
992 __ b(gt, not_int32); | 1019 __ b(gt, not_int32); |
993 // - Bits [21:0] in the mantissa are not null. | 1020 // - Bits [21:0] in the mantissa are not null. |
994 __ tst(src2, Operand(0x3fffff)); | 1021 __ tst(src_mantissa, Operand(0x3fffff)); |
995 __ b(ne, not_int32); | 1022 __ b(ne, not_int32); |
996 | 1023 |
997 // Otherwise the exponent needs to be big enough to shift left all the | 1024 // Otherwise the exponent needs to be big enough to shift left all the |
998 // non zero bits left. So we need the (30 - exponent) last bits of the | 1025 // non zero bits left. So we need the (30 - exponent) last bits of the |
999 // 31 higher bits of the mantissa to be null. | 1026 // 31 higher bits of the mantissa to be null. |
1000 // Because bits [21:0] are null, we can check instead that the | 1027 // Because bits [21:0] are null, we can check instead that the |
1001 // (32 - exponent) last bits of the 32 higher bits of the mantissa are null. | 1028 // (32 - exponent) last bits of the 32 higher bits of the mantissa are null. |
1002 | 1029 |
1003 // Get the 32 higher bits of the mantissa in dst. | 1030 // Get the 32 higher bits of the mantissa in dst. |
1004 __ Ubfx(dst, | 1031 __ Ubfx(dst, |
1005 src2, | 1032 src_mantissa, |
1006 HeapNumber::kMantissaBitsInTopWord, | 1033 HeapNumber::kMantissaBitsInTopWord, |
1007 32 - HeapNumber::kMantissaBitsInTopWord); | 1034 32 - HeapNumber::kMantissaBitsInTopWord); |
1008 __ orr(dst, | 1035 __ orr(dst, |
1009 dst, | 1036 dst, |
1010 Operand(src1, LSL, HeapNumber::kNonMantissaBitsInTopWord)); | 1037 Operand(src_exponent, LSL, HeapNumber::kNonMantissaBitsInTopWord)); |
1011 | 1038 |
1012 // Create the mask and test the lower bits (of the higher bits). | 1039 // Create the mask and test the lower bits (of the higher bits). |
1013 __ rsb(scratch, scratch, Operand(32)); | 1040 __ rsb(scratch, scratch, Operand(32)); |
1014 __ mov(src2, Operand(1)); | 1041 __ mov(src_mantissa, Operand(1)); |
1015 __ mov(src1, Operand(src2, LSL, scratch)); | 1042 __ mov(src_exponent, Operand(src_mantissa, LSL, scratch)); |
1016 __ sub(src1, src1, Operand(1)); | 1043 __ sub(src_exponent, src_exponent, Operand(1)); |
1017 __ tst(dst, src1); | 1044 __ tst(dst, src_exponent); |
1018 __ b(ne, not_int32); | 1045 __ b(ne, not_int32); |
1019 } | 1046 } |
1020 | 1047 |
1021 | 1048 |
1022 void FloatingPointHelper::CallCCodeForDoubleOperation( | 1049 void FloatingPointHelper::CallCCodeForDoubleOperation( |
1023 MacroAssembler* masm, | 1050 MacroAssembler* masm, |
1024 Token::Value op, | 1051 Token::Value op, |
1025 Register heap_number_result, | 1052 Register heap_number_result, |
1026 Register scratch) { | 1053 Register scratch) { |
1027 // Using core registers: | 1054 // Using core registers: |
(...skipping 6559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7587 | 7614 |
7588 __ Pop(lr, r5, r1); | 7615 __ Pop(lr, r5, r1); |
7589 __ Ret(); | 7616 __ Ret(); |
7590 } | 7617 } |
7591 | 7618 |
7592 #undef __ | 7619 #undef __ |
7593 | 7620 |
7594 } } // namespace v8::internal | 7621 } } // namespace v8::internal |
7595 | 7622 |
7596 #endif // V8_TARGET_ARCH_ARM | 7623 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |