| 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 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 |
| 687 __ AssertRootValue(heap_number_map, | 689 __ AssertRootValue(heap_number_map, |
| 688 Heap::kHeapNumberMapRootIndex, | 690 Heap::kHeapNumberMapRootIndex, |
| 689 "HeapNumberMap register clobbered."); | 691 "HeapNumberMap register clobbered."); |
| 690 | 692 |
| 691 Label is_smi, done; | 693 Label is_smi, done; |
| 692 | 694 |
| 693 // Smi-check | 695 // Smi-check |
| 694 __ UntagAndJumpIfSmi(scratch1, object, &is_smi); | 696 __ UntagAndJumpIfSmi(scratch1, object, &is_smi); |
| 695 // Heap number check | 697 // Heap number check |
| 696 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_number); | 698 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_number); |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 871 Register heap_number_map, | 873 Register heap_number_map, |
| 872 Register scratch1, | 874 Register scratch1, |
| 873 Register scratch2, | 875 Register scratch2, |
| 874 FPURegister single_scratch, | 876 FPURegister single_scratch, |
| 875 Label* not_int32) { | 877 Label* not_int32) { |
| 876 ASSERT(!scratch1.is(object) && !scratch2.is(object)); | 878 ASSERT(!scratch1.is(object) && !scratch2.is(object)); |
| 877 ASSERT(!scratch1.is(scratch2)); | 879 ASSERT(!scratch1.is(scratch2)); |
| 878 ASSERT(!heap_number_map.is(object) && | 880 ASSERT(!heap_number_map.is(object) && |
| 879 !heap_number_map.is(scratch1) && | 881 !heap_number_map.is(scratch1) && |
| 880 !heap_number_map.is(scratch2)); | 882 !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)); |
| 881 | 887 |
| 882 Label done, obj_is_not_smi; | 888 Label done, obj_is_not_smi; |
| 883 | 889 |
| 884 __ JumpIfNotSmi(object, &obj_is_not_smi); | 890 __ JumpIfNotSmi(object, &obj_is_not_smi); |
| 885 __ SmiUntag(scratch1, object); | 891 __ SmiUntag(scratch1, object); |
| 886 ConvertIntToDouble(masm, scratch1, destination, double_dst, dst_mantissa, | 892 ConvertIntToDouble(masm, scratch1, destination, double_dst, dst_mantissa, |
| 887 dst_exponent, scratch2, single_scratch); | 893 dst_exponent, scratch2, single_scratch); |
| 888 __ Branch(&done); | 894 __ Branch(&done); |
| 889 | 895 |
| 890 __ bind(&obj_is_not_smi); | 896 __ bind(&obj_is_not_smi); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 907 double_scratch, | 913 double_scratch, |
| 908 except_flag, | 914 except_flag, |
| 909 kCheckForInexactConversion); | 915 kCheckForInexactConversion); |
| 910 | 916 |
| 911 // Jump to not_int32 if the operation did not succeed. | 917 // Jump to not_int32 if the operation did not succeed. |
| 912 __ Branch(not_int32, ne, except_flag, Operand(zero_reg)); | 918 __ Branch(not_int32, ne, except_flag, Operand(zero_reg)); |
| 913 | 919 |
| 914 if (destination == kCoreRegisters) { | 920 if (destination == kCoreRegisters) { |
| 915 __ Move(dst_mantissa, dst_exponent, double_dst); | 921 __ Move(dst_mantissa, dst_exponent, double_dst); |
| 916 } | 922 } |
| 917 | |
| 918 } else { | 923 } else { |
| 919 ASSERT(!scratch1.is(object) && !scratch2.is(object)); | |
| 920 // Load the double value in the destination registers. | 924 // Load the double value in the destination registers. |
| 921 bool save_registers = object.is(dst_mantissa) || object.is(dst_exponent); | |
| 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 __ lw(dst_exponent, FieldMemOperand(object, HeapNumber::kExponentOffset)); | 925 __ lw(dst_exponent, FieldMemOperand(object, HeapNumber::kExponentOffset)); |
| 928 __ lw(dst_mantissa, FieldMemOperand(object, HeapNumber::kMantissaOffset)); | 926 __ lw(dst_mantissa, FieldMemOperand(object, HeapNumber::kMantissaOffset)); |
| 929 | 927 |
| 930 // Check for 0 and -0. | 928 // Check for 0 and -0. |
| 931 Label zero; | |
| 932 __ And(scratch1, dst_exponent, Operand(~HeapNumber::kSignMask)); | 929 __ And(scratch1, dst_exponent, Operand(~HeapNumber::kSignMask)); |
| 933 __ Or(scratch1, scratch1, Operand(dst_mantissa)); | 930 __ Or(scratch1, scratch1, Operand(dst_mantissa)); |
| 934 __ Branch(&zero, eq, scratch1, Operand(zero_reg)); | 931 __ Branch(&done, eq, scratch1, Operand(zero_reg)); |
| 935 | 932 |
| 936 // Check that the value can be exactly represented by a 32-bit integer. | 933 // Check that the value can be exactly represented by a 32-bit integer. |
| 937 // Jump to not_int32 if that's not the case. | 934 // Jump to not_int32 if that's not the case. |
| 938 Label restore_input_and_miss; | |
| 939 DoubleIs32BitInteger(masm, dst_exponent, dst_mantissa, scratch1, scratch2, | 935 DoubleIs32BitInteger(masm, dst_exponent, dst_mantissa, scratch1, scratch2, |
| 940 &restore_input_and_miss); | 936 not_int32); |
| 941 | 937 |
| 942 // dst_* were trashed. Reload the double value. | 938 // dst_* were trashed. Reload the double value. |
| 943 if (save_registers) { | |
| 944 __ Pop(dst_exponent, dst_mantissa); | |
| 945 } | |
| 946 __ lw(dst_exponent, FieldMemOperand(object, HeapNumber::kExponentOffset)); | 939 __ lw(dst_exponent, FieldMemOperand(object, HeapNumber::kExponentOffset)); |
| 947 __ lw(dst_mantissa, FieldMemOperand(object, HeapNumber::kMantissaOffset)); | 940 __ lw(dst_mantissa, FieldMemOperand(object, HeapNumber::kMantissaOffset)); |
| 948 __ Branch(&done); | |
| 949 | |
| 950 __ bind(&restore_input_and_miss); | |
| 951 if (save_registers) { | |
| 952 __ Pop(dst_exponent, dst_mantissa); | |
| 953 } | |
| 954 __ Branch(not_int32); | |
| 955 | |
| 956 __ bind(&zero); | |
| 957 if (save_registers) { | |
| 958 __ Drop(2); | |
| 959 } | |
| 960 } | 941 } |
| 961 | 942 |
| 962 __ bind(&done); | 943 __ bind(&done); |
| 963 } | 944 } |
| 964 | 945 |
| 965 | 946 |
| 966 void FloatingPointHelper::LoadNumberAsInt32(MacroAssembler* masm, | 947 void FloatingPointHelper::LoadNumberAsInt32(MacroAssembler* masm, |
| 967 Register object, | 948 Register object, |
| 968 Register dst, | 949 Register dst, |
| 969 Register heap_number_map, | 950 Register heap_number_map, |
| (...skipping 1730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2700 if (right_type == BinaryOpIC::INT32) { | 2681 if (right_type == BinaryOpIC::INT32) { |
| 2701 FloatingPointHelper::LoadNumberAsInt32Double( | 2682 FloatingPointHelper::LoadNumberAsInt32Double( |
| 2702 masm, right, destination, f14, f16, a2, a3, heap_number_map, | 2683 masm, right, destination, f14, f16, a2, a3, heap_number_map, |
| 2703 scratch1, scratch2, f2, miss); | 2684 scratch1, scratch2, f2, miss); |
| 2704 } else { | 2685 } else { |
| 2705 Label* fail = (right_type == BinaryOpIC::NUMBER) ? miss : not_numbers; | 2686 Label* fail = (right_type == BinaryOpIC::NUMBER) ? miss : not_numbers; |
| 2706 FloatingPointHelper::LoadNumber( | 2687 FloatingPointHelper::LoadNumber( |
| 2707 masm, destination, right, f14, a2, a3, heap_number_map, | 2688 masm, destination, right, f14, a2, a3, heap_number_map, |
| 2708 scratch1, scratch2, fail); | 2689 scratch1, scratch2, fail); |
| 2709 } | 2690 } |
| 2691 // Use scratch3 as left in LoadNumber functions to avoid overwriting of |
| 2692 // left (a0) register. |
| 2693 __ mov(scratch3, left); |
| 2694 |
| 2710 // Load left operand to f12 or a0/a1. This keeps a0/a1 intact if it | 2695 // Load left operand to f12 or a0/a1. This keeps a0/a1 intact if it |
| 2711 // jumps to |miss|. | 2696 // jumps to |miss|. |
| 2712 if (left_type == BinaryOpIC::INT32) { | 2697 if (left_type == BinaryOpIC::INT32) { |
| 2713 FloatingPointHelper::LoadNumberAsInt32Double( | 2698 FloatingPointHelper::LoadNumberAsInt32Double( |
| 2714 masm, left, destination, f12, f16, a0, a1, heap_number_map, | 2699 masm, scratch3, destination, f12, f16, a0, a1, heap_number_map, |
| 2715 scratch1, scratch2, f2, miss); | 2700 scratch1, scratch2, f2, miss); |
| 2716 } else { | 2701 } else { |
| 2717 Label* fail = (left_type == BinaryOpIC::NUMBER) ? miss : not_numbers; | 2702 Label* fail = (left_type == BinaryOpIC::NUMBER) ? miss : not_numbers; |
| 2718 FloatingPointHelper::LoadNumber( | 2703 FloatingPointHelper::LoadNumber( |
| 2719 masm, destination, left, f12, a0, a1, heap_number_map, | 2704 masm, destination, scratch3, f12, a0, a1, heap_number_map, |
| 2720 scratch1, scratch2, fail); | 2705 scratch1, scratch2, fail); |
| 2721 } | 2706 } |
| 2722 } | 2707 } |
| 2723 | 2708 |
| 2724 // Calculate the result. | 2709 // Calculate the result. |
| 2725 if (destination == FloatingPointHelper::kFPURegisters) { | 2710 if (destination == FloatingPointHelper::kFPURegisters) { |
| 2726 // Using FPU registers: | 2711 // Using FPU registers: |
| 2727 // f12: Left value. | 2712 // f12: Left value. |
| 2728 // f14: Right value. | 2713 // f14: Right value. |
| 2729 CpuFeatureScope scope(masm, FPU); | 2714 CpuFeatureScope scope(masm, FPU); |
| (...skipping 5466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8196 __ Pop(ra, t1, a1); | 8181 __ Pop(ra, t1, a1); |
| 8197 __ Ret(); | 8182 __ Ret(); |
| 8198 } | 8183 } |
| 8199 | 8184 |
| 8200 | 8185 |
| 8201 #undef __ | 8186 #undef __ |
| 8202 | 8187 |
| 8203 } } // namespace v8::internal | 8188 } } // namespace v8::internal |
| 8204 | 8189 |
| 8205 #endif // V8_TARGET_ARCH_MIPS | 8190 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |