OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 2686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2697 right_side.Unuse(); | 2697 right_side.Unuse(); |
2698 dest->Split(cc); | 2698 dest->Split(cc); |
2699 } | 2699 } |
2700 } else { | 2700 } else { |
2701 // Neither side is a constant Smi, constant 1-char string or constant null. | 2701 // Neither side is a constant Smi, constant 1-char string or constant null. |
2702 // If either side is a non-smi constant, or known to be a heap number skip | 2702 // If either side is a non-smi constant, or known to be a heap number skip |
2703 // the smi check. | 2703 // the smi check. |
2704 bool known_non_smi = | 2704 bool known_non_smi = |
2705 (left_side.is_constant() && !left_side.handle()->IsSmi()) || | 2705 (left_side.is_constant() && !left_side.handle()->IsSmi()) || |
2706 (right_side.is_constant() && !right_side.handle()->IsSmi()) || | 2706 (right_side.is_constant() && !right_side.handle()->IsSmi()) || |
2707 left_side.number_info().IsDouble() || | 2707 left_side.type_info().IsDouble() || |
2708 right_side.number_info().IsDouble(); | 2708 right_side.type_info().IsDouble(); |
2709 NaNInformation nan_info = | 2709 NaNInformation nan_info = |
2710 (CouldBeNaN(left_side) && CouldBeNaN(right_side)) ? | 2710 (CouldBeNaN(left_side) && CouldBeNaN(right_side)) ? |
2711 kBothCouldBeNaN : | 2711 kBothCouldBeNaN : |
2712 kCantBothBeNaN; | 2712 kCantBothBeNaN; |
2713 | 2713 |
2714 // Inline number comparison handling any combination of smi's and heap | 2714 // Inline number comparison handling any combination of smi's and heap |
2715 // numbers if: | 2715 // numbers if: |
2716 // code is in a loop | 2716 // code is in a loop |
2717 // the compare operation is different from equal | 2717 // the compare operation is different from equal |
2718 // compare is not a for-loop comparison | 2718 // compare is not a for-loop comparison |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2810 | 2810 |
2811 | 2811 |
2812 // Check that the comparison operand is a number. Jump to not_numbers jump | 2812 // Check that the comparison operand is a number. Jump to not_numbers jump |
2813 // target passing the left and right result if the operand is not a number. | 2813 // target passing the left and right result if the operand is not a number. |
2814 static void CheckComparisonOperand(MacroAssembler* masm_, | 2814 static void CheckComparisonOperand(MacroAssembler* masm_, |
2815 Result* operand, | 2815 Result* operand, |
2816 Result* left_side, | 2816 Result* left_side, |
2817 Result* right_side, | 2817 Result* right_side, |
2818 JumpTarget* not_numbers) { | 2818 JumpTarget* not_numbers) { |
2819 // Perform check if operand is not known to be a number. | 2819 // Perform check if operand is not known to be a number. |
2820 if (!operand->number_info().IsNumber()) { | 2820 if (!operand->type_info().IsNumber()) { |
2821 Label done; | 2821 Label done; |
2822 __ test(operand->reg(), Immediate(kSmiTagMask)); | 2822 __ test(operand->reg(), Immediate(kSmiTagMask)); |
2823 __ j(zero, &done); | 2823 __ j(zero, &done); |
2824 __ cmp(FieldOperand(operand->reg(), HeapObject::kMapOffset), | 2824 __ cmp(FieldOperand(operand->reg(), HeapObject::kMapOffset), |
2825 Immediate(Factory::heap_number_map())); | 2825 Immediate(Factory::heap_number_map())); |
2826 not_numbers->Branch(not_equal, left_side, right_side, not_taken); | 2826 not_numbers->Branch(not_equal, left_side, right_side, not_taken); |
2827 __ bind(&done); | 2827 __ bind(&done); |
2828 } | 2828 } |
2829 } | 2829 } |
2830 | 2830 |
2831 | 2831 |
2832 // Load a comparison operand to the FPU stack. This assumes that the operand has | 2832 // Load a comparison operand to the FPU stack. This assumes that the operand has |
2833 // already been checked and is a number. | 2833 // already been checked and is a number. |
2834 static void LoadComparisonOperand(MacroAssembler* masm_, | 2834 static void LoadComparisonOperand(MacroAssembler* masm_, |
2835 Result* operand) { | 2835 Result* operand) { |
2836 Label done; | 2836 Label done; |
2837 if (operand->number_info().IsDouble()) { | 2837 if (operand->type_info().IsDouble()) { |
2838 // Operand is known to be a heap number, just load it. | 2838 // Operand is known to be a heap number, just load it. |
2839 __ fld_d(FieldOperand(operand->reg(), HeapNumber::kValueOffset)); | 2839 __ fld_d(FieldOperand(operand->reg(), HeapNumber::kValueOffset)); |
2840 } else if (operand->number_info().IsSmi()) { | 2840 } else if (operand->type_info().IsSmi()) { |
2841 // Operand is known to be a smi. Convert it to double and keep the original | 2841 // Operand is known to be a smi. Convert it to double and keep the original |
2842 // smi. | 2842 // smi. |
2843 __ SmiUntag(operand->reg()); | 2843 __ SmiUntag(operand->reg()); |
2844 __ push(operand->reg()); | 2844 __ push(operand->reg()); |
2845 __ fild_s(Operand(esp, 0)); | 2845 __ fild_s(Operand(esp, 0)); |
2846 __ pop(operand->reg()); | 2846 __ pop(operand->reg()); |
2847 __ SmiTag(operand->reg()); | 2847 __ SmiTag(operand->reg()); |
2848 } else { | 2848 } else { |
2849 // Operand type not known, check for smi otherwise assume heap number. | 2849 // Operand type not known, check for smi otherwise assume heap number. |
2850 Label smi; | 2850 Label smi; |
(...skipping 15 matching lines...) Expand all Loading... |
2866 | 2866 |
2867 // Load a comparison operand into into a XMM register. Jump to not_numbers jump | 2867 // Load a comparison operand into into a XMM register. Jump to not_numbers jump |
2868 // target passing the left and right result if the operand is not a number. | 2868 // target passing the left and right result if the operand is not a number. |
2869 static void LoadComparisonOperandSSE2(MacroAssembler* masm_, | 2869 static void LoadComparisonOperandSSE2(MacroAssembler* masm_, |
2870 Result* operand, | 2870 Result* operand, |
2871 XMMRegister reg, | 2871 XMMRegister reg, |
2872 Result* left_side, | 2872 Result* left_side, |
2873 Result* right_side, | 2873 Result* right_side, |
2874 JumpTarget* not_numbers) { | 2874 JumpTarget* not_numbers) { |
2875 Label done; | 2875 Label done; |
2876 if (operand->number_info().IsDouble()) { | 2876 if (operand->type_info().IsDouble()) { |
2877 // Operand is known to be a heap number, just load it. | 2877 // Operand is known to be a heap number, just load it. |
2878 __ movdbl(reg, FieldOperand(operand->reg(), HeapNumber::kValueOffset)); | 2878 __ movdbl(reg, FieldOperand(operand->reg(), HeapNumber::kValueOffset)); |
2879 } else if (operand->number_info().IsSmi()) { | 2879 } else if (operand->type_info().IsSmi()) { |
2880 // Operand is known to be a smi. Convert it to double and keep the original | 2880 // Operand is known to be a smi. Convert it to double and keep the original |
2881 // smi. | 2881 // smi. |
2882 __ SmiUntag(operand->reg()); | 2882 __ SmiUntag(operand->reg()); |
2883 __ cvtsi2sd(reg, Operand(operand->reg())); | 2883 __ cvtsi2sd(reg, Operand(operand->reg())); |
2884 __ SmiTag(operand->reg()); | 2884 __ SmiTag(operand->reg()); |
2885 } else { | 2885 } else { |
2886 // Operand type not known, check for smi or heap number. | 2886 // Operand type not known, check for smi or heap number. |
2887 Label smi; | 2887 Label smi; |
2888 __ test(operand->reg(), Immediate(kSmiTagMask)); | 2888 __ test(operand->reg(), Immediate(kSmiTagMask)); |
2889 __ j(zero, &smi); | 2889 __ j(zero, &smi); |
2890 if (!operand->number_info().IsNumber()) { | 2890 if (!operand->type_info().IsNumber()) { |
2891 __ cmp(FieldOperand(operand->reg(), HeapObject::kMapOffset), | 2891 __ cmp(FieldOperand(operand->reg(), HeapObject::kMapOffset), |
2892 Immediate(Factory::heap_number_map())); | 2892 Immediate(Factory::heap_number_map())); |
2893 not_numbers->Branch(not_equal, left_side, right_side, taken); | 2893 not_numbers->Branch(not_equal, left_side, right_side, taken); |
2894 } | 2894 } |
2895 __ movdbl(reg, FieldOperand(operand->reg(), HeapNumber::kValueOffset)); | 2895 __ movdbl(reg, FieldOperand(operand->reg(), HeapNumber::kValueOffset)); |
2896 __ jmp(&done); | 2896 __ jmp(&done); |
2897 | 2897 |
2898 __ bind(&smi); | 2898 __ bind(&smi); |
2899 // Comvert smi to float and keep the original smi. | 2899 // Comvert smi to float and keep the original smi. |
2900 __ SmiUntag(operand->reg()); | 2900 __ SmiUntag(operand->reg()); |
(...skipping 9638 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12539 | 12539 |
12540 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 12540 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
12541 // tagged as a small integer. | 12541 // tagged as a small integer. |
12542 __ bind(&runtime); | 12542 __ bind(&runtime); |
12543 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 12543 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
12544 } | 12544 } |
12545 | 12545 |
12546 #undef __ | 12546 #undef __ |
12547 | 12547 |
12548 } } // namespace v8::internal | 12548 } } // namespace v8::internal |
OLD | NEW |