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

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

Issue 13455006: MIPS: Resolved the rest of soft-float bugs. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | src/mips/codegen-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 666 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 void FloatingPointHelper::LoadNumber(MacroAssembler* masm, 677 void FloatingPointHelper::LoadNumber(MacroAssembler* masm,
678 Destination destination, 678 Destination destination,
679 Register object, 679 Register object,
680 FPURegister dst, 680 FPURegister dst,
681 Register dst1, 681 Register dst1,
682 Register dst2, 682 Register dst2,
683 Register heap_number_map, 683 Register heap_number_map,
684 Register scratch1, 684 Register scratch1,
685 Register scratch2, 685 Register scratch2,
686 Label* not_number) { 686 Label* not_number) {
687 ASSERT(!object.is(dst1) && !object.is(dst2));
688
689 __ AssertRootValue(heap_number_map, 687 __ AssertRootValue(heap_number_map,
690 Heap::kHeapNumberMapRootIndex, 688 Heap::kHeapNumberMapRootIndex,
691 "HeapNumberMap register clobbered."); 689 "HeapNumberMap register clobbered.");
692 690
693 Label is_smi, done; 691 Label is_smi, done;
694 692
695 // Smi-check 693 // Smi-check
696 __ UntagAndJumpIfSmi(scratch1, object, &is_smi); 694 __ UntagAndJumpIfSmi(scratch1, object, &is_smi);
697 // Heap number check 695 // Heap number check
698 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_number); 696 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_number);
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
835 // Clear the first non null bit. 833 // Clear the first non null bit.
836 __ li(scratch2, Operand(1)); 834 __ li(scratch2, Operand(1));
837 __ sllv(scratch2, scratch2, dst_mantissa); 835 __ sllv(scratch2, scratch2, dst_mantissa);
838 __ li(at, -1); 836 __ li(at, -1);
839 __ Xor(scratch2, scratch2, at); 837 __ Xor(scratch2, scratch2, at);
840 __ And(int_scratch, int_scratch, scratch2); 838 __ And(int_scratch, int_scratch, scratch2);
841 839
842 // Get the number of bits to set in the lower part of the mantissa. 840 // Get the number of bits to set in the lower part of the mantissa.
843 __ Subu(scratch2, dst_mantissa, 841 __ Subu(scratch2, dst_mantissa,
844 Operand(HeapNumber::kMantissaBitsInTopWord)); 842 Operand(HeapNumber::kMantissaBitsInTopWord));
845 __ Branch(&fewer_than_20_useful_bits, lt, scratch2, Operand(zero_reg)); 843 __ Branch(&fewer_than_20_useful_bits, le, scratch2, Operand(zero_reg));
846 // Set the higher 20 bits of the mantissa. 844 // Set the higher 20 bits of the mantissa.
847 __ srlv(at, int_scratch, scratch2); 845 __ srlv(at, int_scratch, scratch2);
848 __ or_(dst_exponent, dst_exponent, at); 846 __ or_(dst_exponent, dst_exponent, at);
849 __ li(at, 32); 847 __ li(at, 32);
850 __ subu(scratch2, at, scratch2); 848 __ subu(scratch2, at, scratch2);
851 __ sllv(dst_mantissa, int_scratch, scratch2); 849 __ sllv(dst_mantissa, int_scratch, scratch2);
852 __ Branch(&done); 850 __ Branch(&done);
853 851
854 __ bind(&fewer_than_20_useful_bits); 852 __ bind(&fewer_than_20_useful_bits);
855 __ li(at, HeapNumber::kMantissaBitsInTopWord); 853 __ li(at, HeapNumber::kMantissaBitsInTopWord);
(...skipping 17 matching lines...) Expand all
873 Register heap_number_map, 871 Register heap_number_map,
874 Register scratch1, 872 Register scratch1,
875 Register scratch2, 873 Register scratch2,
876 FPURegister single_scratch, 874 FPURegister single_scratch,
877 Label* not_int32) { 875 Label* not_int32) {
878 ASSERT(!scratch1.is(object) && !scratch2.is(object)); 876 ASSERT(!scratch1.is(object) && !scratch2.is(object));
879 ASSERT(!scratch1.is(scratch2)); 877 ASSERT(!scratch1.is(scratch2));
880 ASSERT(!heap_number_map.is(object) && 878 ASSERT(!heap_number_map.is(object) &&
881 !heap_number_map.is(scratch1) && 879 !heap_number_map.is(scratch1) &&
882 !heap_number_map.is(scratch2)); 880 !heap_number_map.is(scratch2));
883 // ARM uses pop/push and Ldlr to save dst_* and probably object registers in
884 // softfloat path. On MIPS there is no ldlr, 1st lw instruction may overwrite
885 // object register making the 2nd lw invalid.
886 ASSERT(!object.is(dst_mantissa) && !object.is(dst_exponent));
887 881
888 Label done, obj_is_not_smi; 882 Label done, obj_is_not_smi;
889 883
890 __ JumpIfNotSmi(object, &obj_is_not_smi); 884 __ JumpIfNotSmi(object, &obj_is_not_smi);
891 __ SmiUntag(scratch1, object); 885 __ SmiUntag(scratch1, object);
892 ConvertIntToDouble(masm, scratch1, destination, double_dst, dst_mantissa, 886 ConvertIntToDouble(masm, scratch1, destination, double_dst, dst_mantissa,
893 dst_exponent, scratch2, single_scratch); 887 dst_exponent, scratch2, single_scratch);
894 __ Branch(&done); 888 __ Branch(&done);
895 889
896 __ bind(&obj_is_not_smi); 890 __ bind(&obj_is_not_smi);
(...skipping 16 matching lines...) Expand all
913 double_scratch, 907 double_scratch,
914 except_flag, 908 except_flag,
915 kCheckForInexactConversion); 909 kCheckForInexactConversion);
916 910
917 // Jump to not_int32 if the operation did not succeed. 911 // Jump to not_int32 if the operation did not succeed.
918 __ Branch(not_int32, ne, except_flag, Operand(zero_reg)); 912 __ Branch(not_int32, ne, except_flag, Operand(zero_reg));
919 913
920 if (destination == kCoreRegisters) { 914 if (destination == kCoreRegisters) {
921 __ Move(dst_mantissa, dst_exponent, double_dst); 915 __ Move(dst_mantissa, dst_exponent, double_dst);
922 } 916 }
917
923 } else { 918 } else {
919 ASSERT(!scratch1.is(object) && !scratch2.is(object));
924 // Load the double value in the destination registers. 920 // Load the double value in the destination registers.
925 __ lw(dst_exponent, FieldMemOperand(object, HeapNumber::kExponentOffset)); 921 bool save_registers = object.is(dst_mantissa) || object.is(dst_exponent);
926 __ lw(dst_mantissa, FieldMemOperand(object, HeapNumber::kMantissaOffset)); 922 if (save_registers) {
923 // Save both output registers, because the other one probably holds
924 // an important value too.
925 __ Push(dst_exponent, dst_mantissa);
926 }
927 if (object.is(dst_mantissa)) {
928 __ lw(dst_exponent, FieldMemOperand(object, HeapNumber::kExponentOffset));
929 __ lw(dst_mantissa, FieldMemOperand(object, HeapNumber::kMantissaOffset));
930 } else {
931 __ lw(dst_mantissa, FieldMemOperand(object, HeapNumber::kMantissaOffset));
932 __ lw(dst_exponent, FieldMemOperand(object, HeapNumber::kExponentOffset));
933 }
927 934
928 // Check for 0 and -0. 935 // Check for 0 and -0.
936 Label zero;
929 __ And(scratch1, dst_exponent, Operand(~HeapNumber::kSignMask)); 937 __ And(scratch1, dst_exponent, Operand(~HeapNumber::kSignMask));
930 __ Or(scratch1, scratch1, Operand(dst_mantissa)); 938 __ Or(scratch1, scratch1, Operand(dst_mantissa));
931 __ Branch(&done, eq, scratch1, Operand(zero_reg)); 939 __ Branch(&zero, eq, scratch1, Operand(zero_reg));
932 940
933 // Check that the value can be exactly represented by a 32-bit integer. 941 // Check that the value can be exactly represented by a 32-bit integer.
934 // Jump to not_int32 if that's not the case. 942 // Jump to not_int32 if that's not the case.
943 Label restore_input_and_miss;
935 DoubleIs32BitInteger(masm, dst_exponent, dst_mantissa, scratch1, scratch2, 944 DoubleIs32BitInteger(masm, dst_exponent, dst_mantissa, scratch1, scratch2,
936 not_int32); 945 &restore_input_and_miss);
937 946
938 // dst_* were trashed. Reload the double value. 947 // dst_* were trashed. Reload the double value.
939 __ lw(dst_exponent, FieldMemOperand(object, HeapNumber::kExponentOffset)); 948 if (save_registers) {
940 __ lw(dst_mantissa, FieldMemOperand(object, HeapNumber::kMantissaOffset)); 949 __ Pop(dst_exponent, dst_mantissa);
950 }
951 if (object.is(dst_mantissa)) {
952 __ lw(dst_exponent, FieldMemOperand(object, HeapNumber::kExponentOffset));
953 __ lw(dst_mantissa, FieldMemOperand(object, HeapNumber::kMantissaOffset));
954 } else {
955 __ lw(dst_mantissa, FieldMemOperand(object, HeapNumber::kMantissaOffset));
956 __ lw(dst_exponent, FieldMemOperand(object, HeapNumber::kExponentOffset));
957 }
958
959 __ Branch(&done);
960
961 __ bind(&restore_input_and_miss);
962 if (save_registers) {
963 __ Pop(dst_exponent, dst_mantissa);
964 }
965 __ Branch(not_int32);
966
967 __ bind(&zero);
968 if (save_registers) {
969 __ Drop(2);
970 }
941 } 971 }
942 972
943 __ bind(&done); 973 __ bind(&done);
944 } 974 }
945 975
946 976
947 void FloatingPointHelper::LoadNumberAsInt32(MacroAssembler* masm, 977 void FloatingPointHelper::LoadNumberAsInt32(MacroAssembler* masm,
948 Register object, 978 Register object,
949 Register dst, 979 Register dst,
950 Register heap_number_map, 980 Register heap_number_map,
(...skipping 1730 matching lines...) Expand 10 before | Expand all | Expand 10 after
2681 if (right_type == BinaryOpIC::INT32) { 2711 if (right_type == BinaryOpIC::INT32) {
2682 FloatingPointHelper::LoadNumberAsInt32Double( 2712 FloatingPointHelper::LoadNumberAsInt32Double(
2683 masm, right, destination, f14, f16, a2, a3, heap_number_map, 2713 masm, right, destination, f14, f16, a2, a3, heap_number_map,
2684 scratch1, scratch2, f2, miss); 2714 scratch1, scratch2, f2, miss);
2685 } else { 2715 } else {
2686 Label* fail = (right_type == BinaryOpIC::NUMBER) ? miss : not_numbers; 2716 Label* fail = (right_type == BinaryOpIC::NUMBER) ? miss : not_numbers;
2687 FloatingPointHelper::LoadNumber( 2717 FloatingPointHelper::LoadNumber(
2688 masm, destination, right, f14, a2, a3, heap_number_map, 2718 masm, destination, right, f14, a2, a3, heap_number_map,
2689 scratch1, scratch2, fail); 2719 scratch1, scratch2, fail);
2690 } 2720 }
2691 // Use scratch3 as left in LoadNumber functions to avoid overwriting of
2692 // left (a0) register.
2693 __ mov(scratch3, left);
2694
2695 // Load left operand to f12 or a0/a1. This keeps a0/a1 intact if it 2721 // Load left operand to f12 or a0/a1. This keeps a0/a1 intact if it
2696 // jumps to |miss|. 2722 // jumps to |miss|.
2697 if (left_type == BinaryOpIC::INT32) { 2723 if (left_type == BinaryOpIC::INT32) {
2698 FloatingPointHelper::LoadNumberAsInt32Double( 2724 FloatingPointHelper::LoadNumberAsInt32Double(
2699 masm, scratch3, destination, f12, f16, a0, a1, heap_number_map, 2725 masm, left, destination, f12, f16, a0, a1, heap_number_map,
2700 scratch1, scratch2, f2, miss); 2726 scratch1, scratch2, f2, miss);
2701 } else { 2727 } else {
2702 Label* fail = (left_type == BinaryOpIC::NUMBER) ? miss : not_numbers; 2728 Label* fail = (left_type == BinaryOpIC::NUMBER) ? miss : not_numbers;
2703 FloatingPointHelper::LoadNumber( 2729 FloatingPointHelper::LoadNumber(
2704 masm, destination, scratch3, f12, a0, a1, heap_number_map, 2730 masm, destination, left, f12, a0, a1, heap_number_map,
2705 scratch1, scratch2, fail); 2731 scratch1, scratch2, fail);
2706 } 2732 }
2707 } 2733 }
2708 2734
2709 // Calculate the result. 2735 // Calculate the result.
2710 if (destination == FloatingPointHelper::kFPURegisters) { 2736 if (destination == FloatingPointHelper::kFPURegisters) {
2711 // Using FPU registers: 2737 // Using FPU registers:
2712 // f12: Left value. 2738 // f12: Left value.
2713 // f14: Right value. 2739 // f14: Right value.
2714 CpuFeatureScope scope(masm, FPU); 2740 CpuFeatureScope scope(masm, FPU);
(...skipping 5440 matching lines...) Expand 10 before | Expand all | Expand 10 after
8155 __ Pop(ra, t1, a1); 8181 __ Pop(ra, t1, a1);
8156 __ Ret(); 8182 __ Ret();
8157 } 8183 }
8158 8184
8159 8185
8160 #undef __ 8186 #undef __
8161 8187
8162 } } // namespace v8::internal 8188 } } // namespace v8::internal
8163 8189
8164 #endif // V8_TARGET_ARCH_MIPS 8190 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « no previous file | src/mips/codegen-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698