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

Side by Side Diff: src/mips/code-stubs-mips.cc

Issue 11308158: MIPS: Fix register confusion in non-VFP3 BinaryOpStubs on ARM (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased on r13080 Created 8 years 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | src/mips/stub-cache-mips.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 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 716 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 scratch3); 727 scratch3);
728 728
729 __ bind(&done); 729 __ bind(&done);
730 } 730 }
731 731
732 732
733 void FloatingPointHelper::ConvertIntToDouble(MacroAssembler* masm, 733 void FloatingPointHelper::ConvertIntToDouble(MacroAssembler* masm,
734 Register int_scratch, 734 Register int_scratch,
735 Destination destination, 735 Destination destination,
736 FPURegister double_dst, 736 FPURegister double_dst,
737 Register dst1, 737 Register dst_mantissa,
738 Register dst2, 738 Register dst_exponent,
739 Register scratch2, 739 Register scratch2,
740 FPURegister single_scratch) { 740 FPURegister single_scratch) {
741 ASSERT(!int_scratch.is(scratch2)); 741 ASSERT(!int_scratch.is(scratch2));
742 ASSERT(!int_scratch.is(dst1)); 742 ASSERT(!int_scratch.is(dst_mantissa));
743 ASSERT(!int_scratch.is(dst2)); 743 ASSERT(!int_scratch.is(dst_exponent));
744 744
745 Label done; 745 Label done;
746 746
747 if (CpuFeatures::IsSupported(FPU)) { 747 if (CpuFeatures::IsSupported(FPU)) {
748 CpuFeatures::Scope scope(FPU); 748 CpuFeatures::Scope scope(FPU);
749 __ mtc1(int_scratch, single_scratch); 749 __ mtc1(int_scratch, single_scratch);
750 __ cvt_d_w(double_dst, single_scratch); 750 __ cvt_d_w(double_dst, single_scratch);
751 if (destination == kCoreRegisters) { 751 if (destination == kCoreRegisters) {
752 __ Move(dst1, dst2, double_dst); 752 __ Move(dst_mantissa, dst_exponent, double_dst);
753 } 753 }
754 } else { 754 } else {
755 Label fewer_than_20_useful_bits; 755 Label fewer_than_20_useful_bits;
756 // Expected output: 756 // Expected output:
757 // | dst2 | dst1 | 757 // | dst_exponent | dst_mantissa |
758 // | s | exp | mantissa | 758 // | s | exp | mantissa |
759 759
760 // Check for zero. 760 // Check for zero.
761 __ mov(dst2, int_scratch); 761 __ mov(dst_exponent, int_scratch);
762 __ mov(dst1, int_scratch); 762 __ mov(dst_mantissa, int_scratch);
763 __ Branch(&done, eq, int_scratch, Operand(zero_reg)); 763 __ Branch(&done, eq, int_scratch, Operand(zero_reg));
764 764
765 // Preload the sign of the value. 765 // Preload the sign of the value.
766 __ And(dst2, int_scratch, Operand(HeapNumber::kSignMask)); 766 __ And(dst_exponent, int_scratch, Operand(HeapNumber::kSignMask));
767 // Get the absolute value of the object (as an unsigned integer). 767 // Get the absolute value of the object (as an unsigned integer).
768 Label skip_sub; 768 Label skip_sub;
769 __ Branch(&skip_sub, ge, dst2, Operand(zero_reg)); 769 __ Branch(&skip_sub, ge, dst_exponent, Operand(zero_reg));
770 __ Subu(int_scratch, zero_reg, int_scratch); 770 __ Subu(int_scratch, zero_reg, int_scratch);
771 __ bind(&skip_sub); 771 __ bind(&skip_sub);
772 772
773 // Get mantissa[51:20]. 773 // Get mantissa[51:20].
774 774
775 // Get the position of the first set bit. 775 // Get the position of the first set bit.
776 __ Clz(dst1, int_scratch); 776 __ Clz(dst_mantissa, int_scratch);
777 __ li(scratch2, 31); 777 __ li(scratch2, 31);
778 __ Subu(dst1, scratch2, dst1); 778 __ Subu(dst_mantissa, scratch2, dst_mantissa);
779 779
780 // Set the exponent. 780 // Set the exponent.
781 __ Addu(scratch2, dst1, Operand(HeapNumber::kExponentBias)); 781 __ Addu(scratch2, dst_mantissa, Operand(HeapNumber::kExponentBias));
782 __ Ins(dst2, scratch2, 782 __ Ins(dst_exponent, scratch2,
783 HeapNumber::kExponentShift, HeapNumber::kExponentBits); 783 HeapNumber::kExponentShift, HeapNumber::kExponentBits);
784 784
785 // Clear the first non null bit. 785 // Clear the first non null bit.
786 __ li(scratch2, Operand(1)); 786 __ li(scratch2, Operand(1));
787 __ sllv(scratch2, scratch2, dst1); 787 __ sllv(scratch2, scratch2, dst_mantissa);
788 __ li(at, -1); 788 __ li(at, -1);
789 __ Xor(scratch2, scratch2, at); 789 __ Xor(scratch2, scratch2, at);
790 __ And(int_scratch, int_scratch, scratch2); 790 __ And(int_scratch, int_scratch, scratch2);
791 791
792 // Get the number of bits to set in the lower part of the mantissa. 792 // Get the number of bits to set in the lower part of the mantissa.
793 __ Subu(scratch2, dst1, Operand(HeapNumber::kMantissaBitsInTopWord)); 793 __ Subu(scratch2, dst_mantissa,
794 Operand(HeapNumber::kMantissaBitsInTopWord));
794 __ Branch(&fewer_than_20_useful_bits, lt, scratch2, Operand(zero_reg)); 795 __ Branch(&fewer_than_20_useful_bits, lt, scratch2, Operand(zero_reg));
795 // Set the higher 20 bits of the mantissa. 796 // Set the higher 20 bits of the mantissa.
796 __ srlv(at, int_scratch, scratch2); 797 __ srlv(at, int_scratch, scratch2);
797 __ or_(dst2, dst2, at); 798 __ or_(dst_exponent, dst_exponent, at);
798 __ li(at, 32); 799 __ li(at, 32);
799 __ subu(scratch2, at, scratch2); 800 __ subu(scratch2, at, scratch2);
800 __ sllv(dst1, int_scratch, scratch2); 801 __ sllv(dst_mantissa, int_scratch, scratch2);
801 __ Branch(&done); 802 __ Branch(&done);
802 803
803 __ bind(&fewer_than_20_useful_bits); 804 __ bind(&fewer_than_20_useful_bits);
804 __ li(at, HeapNumber::kMantissaBitsInTopWord); 805 __ li(at, HeapNumber::kMantissaBitsInTopWord);
805 __ subu(scratch2, at, dst1); 806 __ subu(scratch2, at, dst_mantissa);
806 __ sllv(scratch2, int_scratch, scratch2); 807 __ sllv(scratch2, int_scratch, scratch2);
807 __ Or(dst2, dst2, scratch2); 808 __ Or(dst_exponent, dst_exponent, scratch2);
808 // Set dst1 to 0. 809 // Set dst_mantissa to 0.
809 __ mov(dst1, zero_reg); 810 __ mov(dst_mantissa, zero_reg);
810 } 811 }
811 __ bind(&done); 812 __ bind(&done);
812 } 813 }
813 814
814 815
815 void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm, 816 void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm,
816 Register object, 817 Register object,
817 Destination destination, 818 Destination destination,
818 DoubleRegister double_dst, 819 DoubleRegister double_dst,
819 DoubleRegister double_scratch, 820 DoubleRegister double_scratch,
820 Register dst1, 821 Register dst_mantissa,
821 Register dst2, 822 Register dst_exponent,
822 Register heap_number_map, 823 Register heap_number_map,
823 Register scratch1, 824 Register scratch1,
824 Register scratch2, 825 Register scratch2,
825 FPURegister single_scratch, 826 FPURegister single_scratch,
826 Label* not_int32) { 827 Label* not_int32) {
827 ASSERT(!scratch1.is(object) && !scratch2.is(object)); 828 ASSERT(!scratch1.is(object) && !scratch2.is(object));
828 ASSERT(!scratch1.is(scratch2)); 829 ASSERT(!scratch1.is(scratch2));
829 ASSERT(!heap_number_map.is(object) && 830 ASSERT(!heap_number_map.is(object) &&
830 !heap_number_map.is(scratch1) && 831 !heap_number_map.is(scratch1) &&
831 !heap_number_map.is(scratch2)); 832 !heap_number_map.is(scratch2));
832 833
833 Label done, obj_is_not_smi; 834 Label done, obj_is_not_smi;
834 835
835 __ JumpIfNotSmi(object, &obj_is_not_smi); 836 __ JumpIfNotSmi(object, &obj_is_not_smi);
836 __ SmiUntag(scratch1, object); 837 __ SmiUntag(scratch1, object);
837 ConvertIntToDouble(masm, scratch1, destination, double_dst, dst1, dst2, 838 ConvertIntToDouble(masm, scratch1, destination, double_dst, dst_mantissa,
838 scratch2, single_scratch); 839 dst_exponent, scratch2, single_scratch);
839 __ Branch(&done); 840 __ Branch(&done);
840 841
841 __ bind(&obj_is_not_smi); 842 __ bind(&obj_is_not_smi);
842 __ AssertRootValue(heap_number_map, 843 __ AssertRootValue(heap_number_map,
843 Heap::kHeapNumberMapRootIndex, 844 Heap::kHeapNumberMapRootIndex,
844 "HeapNumberMap register clobbered."); 845 "HeapNumberMap register clobbered.");
845 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_int32); 846 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_int32);
846 847
847 // Load the number. 848 // Load the number.
848 if (CpuFeatures::IsSupported(FPU)) { 849 if (CpuFeatures::IsSupported(FPU)) {
849 CpuFeatures::Scope scope(FPU); 850 CpuFeatures::Scope scope(FPU);
850 // Load the double value. 851 // Load the double value.
851 __ ldc1(double_dst, FieldMemOperand(object, HeapNumber::kValueOffset)); 852 __ ldc1(double_dst, FieldMemOperand(object, HeapNumber::kValueOffset));
852 853
853 Register except_flag = scratch2; 854 Register except_flag = scratch2;
854 __ EmitFPUTruncate(kRoundToZero, 855 __ EmitFPUTruncate(kRoundToZero,
855 scratch1, 856 scratch1,
856 double_dst, 857 double_dst,
857 at, 858 at,
858 double_scratch, 859 double_scratch,
859 except_flag, 860 except_flag,
860 kCheckForInexactConversion); 861 kCheckForInexactConversion);
861 862
862 // Jump to not_int32 if the operation did not succeed. 863 // Jump to not_int32 if the operation did not succeed.
863 __ Branch(not_int32, ne, except_flag, Operand(zero_reg)); 864 __ Branch(not_int32, ne, except_flag, Operand(zero_reg));
864 865
865 if (destination == kCoreRegisters) { 866 if (destination == kCoreRegisters) {
866 __ Move(dst1, dst2, double_dst); 867 __ Move(dst_mantissa, dst_exponent, double_dst);
867 } 868 }
868 869
869 } else { 870 } else {
870 ASSERT(!scratch1.is(object) && !scratch2.is(object)); 871 ASSERT(!scratch1.is(object) && !scratch2.is(object));
871 // Load the double value in the destination registers. 872 // Load the double value in the destination registers.
872 __ lw(dst2, FieldMemOperand(object, HeapNumber::kExponentOffset)); 873 bool save_registers = object.is(dst_mantissa) || object.is(dst_exponent);
873 __ lw(dst1, FieldMemOperand(object, HeapNumber::kMantissaOffset)); 874 if (save_registers) {
875 // Save both output registers, because the other one probably holds
876 // an important value too.
877 __ Push(dst_exponent, dst_mantissa);
878 }
879 __ lw(dst_exponent, FieldMemOperand(object, HeapNumber::kExponentOffset));
880 __ lw(dst_mantissa, FieldMemOperand(object, HeapNumber::kMantissaOffset));
874 881
875 // Check for 0 and -0. 882 // Check for 0 and -0.
876 __ And(scratch1, dst1, Operand(~HeapNumber::kSignMask)); 883 Label zero;
877 __ Or(scratch1, scratch1, Operand(dst2)); 884 __ And(scratch1, dst_exponent, Operand(~HeapNumber::kSignMask));
878 __ Branch(&done, eq, scratch1, Operand(zero_reg)); 885 __ Or(scratch1, scratch1, Operand(dst_mantissa));
886 __ Branch(&zero, eq, scratch1, Operand(zero_reg));
879 887
880 // Check that the value can be exactly represented by a 32-bit integer. 888 // Check that the value can be exactly represented by a 32-bit integer.
881 // Jump to not_int32 if that's not the case. 889 // Jump to not_int32 if that's not the case.
882 DoubleIs32BitInteger(masm, dst1, dst2, scratch1, scratch2, not_int32); 890 Label restore_input_and_miss;
891 DoubleIs32BitInteger(masm, dst_exponent, dst_mantissa, scratch1, scratch2,
892 &restore_input_and_miss);
883 893
884 // dst1 and dst2 were trashed. Reload the double value. 894 // dst_* were trashed. Reload the double value.
885 __ lw(dst2, FieldMemOperand(object, HeapNumber::kExponentOffset)); 895 if (save_registers) {
886 __ lw(dst1, FieldMemOperand(object, HeapNumber::kMantissaOffset)); 896 __ Pop(dst_exponent, dst_mantissa);
897 }
898 __ lw(dst_exponent, FieldMemOperand(object, HeapNumber::kExponentOffset));
899 __ lw(dst_mantissa, FieldMemOperand(object, HeapNumber::kMantissaOffset));
900 __ Branch(&done);
901
902 __ bind(&restore_input_and_miss);
903 if (save_registers) {
904 __ Pop(dst_exponent, dst_mantissa);
905 }
906 __ Branch(not_int32);
907
908 __ bind(&zero);
909 if (save_registers) {
910 __ Drop(2);
911 }
887 } 912 }
888 913
889 __ bind(&done); 914 __ bind(&done);
890 } 915 }
891 916
892 917
893 void FloatingPointHelper::LoadNumberAsInt32(MacroAssembler* masm, 918 void FloatingPointHelper::LoadNumberAsInt32(MacroAssembler* masm,
894 Register object, 919 Register object,
895 Register dst, 920 Register dst,
896 Register heap_number_map, 921 Register heap_number_map,
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
972 __ Branch(not_int32, ne, object, Operand(at)); 997 __ Branch(not_int32, ne, object, Operand(at));
973 // |undefined| is truncated to 0. 998 // |undefined| is truncated to 0.
974 __ li(dst, Operand(Smi::FromInt(0))); 999 __ li(dst, Operand(Smi::FromInt(0)));
975 // Fall through. 1000 // Fall through.
976 1001
977 __ bind(&done); 1002 __ bind(&done);
978 } 1003 }
979 1004
980 1005
981 void FloatingPointHelper::DoubleIs32BitInteger(MacroAssembler* masm, 1006 void FloatingPointHelper::DoubleIs32BitInteger(MacroAssembler* masm,
982 Register src1, 1007 Register src_exponent,
983 Register src2, 1008 Register src_mantissa,
984 Register dst, 1009 Register dst,
985 Register scratch, 1010 Register scratch,
986 Label* not_int32) { 1011 Label* not_int32) {
987 // Get exponent alone in scratch. 1012 // Get exponent alone in scratch.
988 __ Ext(scratch, 1013 __ Ext(scratch,
989 src1, 1014 src_exponent,
990 HeapNumber::kExponentShift, 1015 HeapNumber::kExponentShift,
991 HeapNumber::kExponentBits); 1016 HeapNumber::kExponentBits);
992 1017
993 // Substract the bias from the exponent. 1018 // Substract the bias from the exponent.
994 __ Subu(scratch, scratch, Operand(HeapNumber::kExponentBias)); 1019 __ Subu(scratch, scratch, Operand(HeapNumber::kExponentBias));
995 1020
996 // src1: higher (exponent) part of the double value. 1021 // src1: higher (exponent) part of the double value.
997 // src2: lower (mantissa) part of the double value. 1022 // src2: lower (mantissa) part of the double value.
998 // scratch: unbiased exponent. 1023 // scratch: unbiased exponent.
999 1024
1000 // Fast cases. Check for obvious non 32-bit integer values. 1025 // Fast cases. Check for obvious non 32-bit integer values.
1001 // Negative exponent cannot yield 32-bit integers. 1026 // Negative exponent cannot yield 32-bit integers.
1002 __ Branch(not_int32, lt, scratch, Operand(zero_reg)); 1027 __ Branch(not_int32, lt, scratch, Operand(zero_reg));
1003 // Exponent greater than 31 cannot yield 32-bit integers. 1028 // Exponent greater than 31 cannot yield 32-bit integers.
1004 // Also, a positive value with an exponent equal to 31 is outside of the 1029 // Also, a positive value with an exponent equal to 31 is outside of the
1005 // signed 32-bit integer range. 1030 // signed 32-bit integer range.
1006 // Another way to put it is that if (exponent - signbit) > 30 then the 1031 // Another way to put it is that if (exponent - signbit) > 30 then the
1007 // number cannot be represented as an int32. 1032 // number cannot be represented as an int32.
1008 Register tmp = dst; 1033 Register tmp = dst;
1009 __ srl(at, src1, 31); 1034 __ srl(at, src_exponent, 31);
1010 __ subu(tmp, scratch, at); 1035 __ subu(tmp, scratch, at);
1011 __ Branch(not_int32, gt, tmp, Operand(30)); 1036 __ Branch(not_int32, gt, tmp, Operand(30));
1012 // - Bits [21:0] in the mantissa are not null. 1037 // - Bits [21:0] in the mantissa are not null.
1013 __ And(tmp, src2, 0x3fffff); 1038 __ And(tmp, src_mantissa, 0x3fffff);
1014 __ Branch(not_int32, ne, tmp, Operand(zero_reg)); 1039 __ Branch(not_int32, ne, tmp, Operand(zero_reg));
1015 1040
1016 // Otherwise the exponent needs to be big enough to shift left all the 1041 // Otherwise the exponent needs to be big enough to shift left all the
1017 // non zero bits left. So we need the (30 - exponent) last bits of the 1042 // non zero bits left. So we need the (30 - exponent) last bits of the
1018 // 31 higher bits of the mantissa to be null. 1043 // 31 higher bits of the mantissa to be null.
1019 // Because bits [21:0] are null, we can check instead that the 1044 // Because bits [21:0] are null, we can check instead that the
1020 // (32 - exponent) last bits of the 32 higher bits of the mantissa are null. 1045 // (32 - exponent) last bits of the 32 higher bits of the mantissa are null.
1021 1046
1022 // Get the 32 higher bits of the mantissa in dst. 1047 // Get the 32 higher bits of the mantissa in dst.
1023 __ Ext(dst, 1048 __ Ext(dst,
1024 src2, 1049 src_mantissa,
1025 HeapNumber::kMantissaBitsInTopWord, 1050 HeapNumber::kMantissaBitsInTopWord,
1026 32 - HeapNumber::kMantissaBitsInTopWord); 1051 32 - HeapNumber::kMantissaBitsInTopWord);
1027 __ sll(at, src1, HeapNumber::kNonMantissaBitsInTopWord); 1052 __ sll(at, src_exponent, HeapNumber::kNonMantissaBitsInTopWord);
1028 __ or_(dst, dst, at); 1053 __ or_(dst, dst, at);
1029 1054
1030 // Create the mask and test the lower bits (of the higher bits). 1055 // Create the mask and test the lower bits (of the higher bits).
1031 __ li(at, 32); 1056 __ li(at, 32);
1032 __ subu(scratch, at, scratch); 1057 __ subu(scratch, at, scratch);
1033 __ li(src2, 1); 1058 __ li(src_mantissa, 1);
1034 __ sllv(src1, src2, scratch); 1059 __ sllv(src_exponent, src_mantissa, scratch);
1035 __ Subu(src1, src1, Operand(1)); 1060 __ Subu(src_exponent, src_exponent, Operand(1));
1036 __ And(src1, dst, src1); 1061 __ And(src_exponent, dst, src_exponent);
1037 __ Branch(not_int32, ne, src1, Operand(zero_reg)); 1062 __ Branch(not_int32, ne, src_exponent, Operand(zero_reg));
1038 } 1063 }
1039 1064
1040 1065
1041 void FloatingPointHelper::CallCCodeForDoubleOperation( 1066 void FloatingPointHelper::CallCCodeForDoubleOperation(
1042 MacroAssembler* masm, 1067 MacroAssembler* masm,
1043 Token::Value op, 1068 Token::Value op,
1044 Register heap_number_result, 1069 Register heap_number_result,
1045 Register scratch) { 1070 Register scratch) {
1046 // Using core registers: 1071 // Using core registers:
1047 // a0: Left value (least significant part of mantissa). 1072 // a0: Left value (least significant part of mantissa).
(...skipping 6740 matching lines...) Expand 10 before | Expand all | Expand 10 after
7788 __ Pop(ra, t1, a1); 7813 __ Pop(ra, t1, a1);
7789 __ Ret(); 7814 __ Ret();
7790 } 7815 }
7791 7816
7792 7817
7793 #undef __ 7818 #undef __
7794 7819
7795 } } // namespace v8::internal 7820 } } // namespace v8::internal
7796 7821
7797 #endif // V8_TARGET_ARCH_MIPS 7822 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « no previous file | src/mips/stub-cache-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698