| 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 871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 882 Register dst_; | 882 Register dst_; |
| 883 Register left_; | 883 Register left_; |
| 884 Register right_; | 884 Register right_; |
| 885 OverwriteMode mode_; | 885 OverwriteMode mode_; |
| 886 }; | 886 }; |
| 887 | 887 |
| 888 | 888 |
| 889 void DeferredInlineBinaryOperation::Generate() { | 889 void DeferredInlineBinaryOperation::Generate() { |
| 890 Label done; | 890 Label done; |
| 891 if (CpuFeatures::IsSupported(SSE2) && ((op_ == Token::ADD) || | 891 if (CpuFeatures::IsSupported(SSE2) && ((op_ == Token::ADD) || |
| 892 (op_ ==Token::SUB) || | 892 (op_ == Token::SUB) || |
| 893 (op_ == Token::MUL) || | 893 (op_ == Token::MUL) || |
| 894 (op_ == Token::DIV))) { | 894 (op_ == Token::DIV))) { |
| 895 CpuFeatures::Scope use_sse2(SSE2); | 895 CpuFeatures::Scope use_sse2(SSE2); |
| 896 Label call_runtime, after_alloc_failure; | 896 Label call_runtime, after_alloc_failure; |
| 897 Label left_smi, right_smi, load_right, do_op; | 897 Label left_smi, right_smi, load_right, do_op, allocate_dst; |
| 898 __ test(left_, Immediate(kSmiTagMask)); | 898 if (left_.is(right_)) { |
| 899 __ j(zero, &left_smi); | 899 __ test(left_, Immediate(kSmiTagMask)); |
| 900 __ cmp(FieldOperand(left_, HeapObject::kMapOffset), | 900 __ j(zero, &left_smi); |
| 901 Factory::heap_number_map()); | 901 __ cmp(FieldOperand(left_, HeapObject::kMapOffset), |
| 902 __ j(not_equal, &call_runtime); | 902 Factory::heap_number_map()); |
| 903 __ movdbl(xmm0, FieldOperand(left_, HeapNumber::kValueOffset)); | 903 __ j(not_equal, &call_runtime); |
| 904 if (mode_ == OVERWRITE_LEFT) { | 904 __ movdbl(xmm0, FieldOperand(left_, HeapNumber::kValueOffset)); |
| 905 __ mov(dst_, left_); | 905 if (mode_ == OVERWRITE_LEFT || mode_ == OVERWRITE_RIGHT) { |
| 906 } | 906 __ mov(dst_, left_); |
| 907 __ jmp(&load_right); | 907 __ jmp(&do_op); |
| 908 } else { |
| 909 __ jmp(&allocate_dst); |
| 910 } |
| 908 | 911 |
| 909 __ bind(&left_smi); | 912 __ bind(&left_smi); |
| 910 __ SmiUntag(left_); | 913 __ SmiUntag(left_); |
| 911 __ cvtsi2sd(xmm0, Operand(left_)); | 914 __ cvtsi2sd(xmm0, Operand(left_)); |
| 912 __ SmiTag(left_); | 915 __ SmiTag(left_); |
| 913 if (mode_ == OVERWRITE_LEFT) { | 916 |
| 914 Label alloc_failure; | 917 __ bind(&allocate_dst); |
| 915 __ push(left_); | 918 __ push(left_); |
| 916 __ AllocateHeapNumber(dst_, left_, no_reg, &after_alloc_failure); | 919 __ AllocateHeapNumber(dst_, left_, no_reg, &after_alloc_failure); |
| 917 __ pop(left_); | 920 __ pop(left_); |
| 918 } | |
| 919 | 921 |
| 920 __ bind(&load_right); | 922 __ bind(&do_op); |
| 921 __ test(right_, Immediate(kSmiTagMask)); | 923 switch (op_) { |
| 922 __ j(zero, &right_smi); | 924 case Token::ADD: __ addsd(xmm0, xmm0); break; |
| 923 __ cmp(FieldOperand(right_, HeapObject::kMapOffset), | 925 case Token::SUB: __ subsd(xmm0, xmm0); break; |
| 924 Factory::heap_number_map()); | 926 case Token::MUL: __ mulsd(xmm0, xmm0); break; |
| 925 __ j(not_equal, &call_runtime); | 927 case Token::DIV: __ divsd(xmm0, xmm0); break; |
| 926 __ movdbl(xmm1, FieldOperand(right_, HeapNumber::kValueOffset)); | 928 default: UNREACHABLE(); |
| 927 if (mode_ == OVERWRITE_RIGHT) { | 929 } |
| 928 __ mov(dst_, right_); | 930 } else { |
| 929 } else if (mode_ == NO_OVERWRITE) { | 931 __ test(left_, Immediate(kSmiTagMask)); |
| 930 Label alloc_failure; | 932 __ j(zero, &left_smi); |
| 931 __ push(left_); | 933 __ cmp(FieldOperand(left_, HeapObject::kMapOffset), |
| 932 __ AllocateHeapNumber(dst_, left_, no_reg, &after_alloc_failure); | 934 Factory::heap_number_map()); |
| 933 __ pop(left_); | 935 __ j(not_equal, &call_runtime); |
| 934 } | 936 __ movdbl(xmm0, FieldOperand(left_, HeapNumber::kValueOffset)); |
| 935 __ jmp(&do_op); | 937 if (mode_ == OVERWRITE_LEFT) { |
| 938 __ mov(dst_, left_); |
| 939 } |
| 940 __ jmp(&load_right); |
| 936 | 941 |
| 937 __ bind(&right_smi); | 942 __ bind(&left_smi); |
| 938 __ SmiUntag(right_); | 943 __ SmiUntag(left_); |
| 939 __ cvtsi2sd(xmm1, Operand(right_)); | 944 __ cvtsi2sd(xmm0, Operand(left_)); |
| 940 __ SmiTag(right_); | 945 __ SmiTag(left_); |
| 941 if (mode_ == OVERWRITE_RIGHT || mode_ == NO_OVERWRITE) { | 946 if (mode_ == OVERWRITE_LEFT) { |
| 942 Label alloc_failure; | 947 Label alloc_failure; |
| 943 __ push(left_); | 948 __ push(left_); |
| 944 __ AllocateHeapNumber(dst_, left_, no_reg, &after_alloc_failure); | 949 __ AllocateHeapNumber(dst_, left_, no_reg, &after_alloc_failure); |
| 945 __ pop(left_); | 950 __ pop(left_); |
| 946 } | 951 } |
| 947 | 952 |
| 948 __ bind(&do_op); | 953 __ bind(&load_right); |
| 949 switch (op_) { | 954 __ test(right_, Immediate(kSmiTagMask)); |
| 950 case Token::ADD: __ addsd(xmm0, xmm1); break; | 955 __ j(zero, &right_smi); |
| 951 case Token::SUB: __ subsd(xmm0, xmm1); break; | 956 __ cmp(FieldOperand(right_, HeapObject::kMapOffset), |
| 952 case Token::MUL: __ mulsd(xmm0, xmm1); break; | 957 Factory::heap_number_map()); |
| 953 case Token::DIV: __ divsd(xmm0, xmm1); break; | 958 __ j(not_equal, &call_runtime); |
| 954 default: UNREACHABLE(); | 959 __ movdbl(xmm1, FieldOperand(right_, HeapNumber::kValueOffset)); |
| 960 if (mode_ == OVERWRITE_RIGHT) { |
| 961 __ mov(dst_, right_); |
| 962 } else if (mode_ == NO_OVERWRITE) { |
| 963 Label alloc_failure; |
| 964 __ push(left_); |
| 965 __ AllocateHeapNumber(dst_, left_, no_reg, &after_alloc_failure); |
| 966 __ pop(left_); |
| 967 } |
| 968 __ jmp(&do_op); |
| 969 |
| 970 __ bind(&right_smi); |
| 971 __ SmiUntag(right_); |
| 972 __ cvtsi2sd(xmm1, Operand(right_)); |
| 973 __ SmiTag(right_); |
| 974 if (mode_ == OVERWRITE_RIGHT || mode_ == NO_OVERWRITE) { |
| 975 Label alloc_failure; |
| 976 __ push(left_); |
| 977 __ AllocateHeapNumber(dst_, left_, no_reg, &after_alloc_failure); |
| 978 __ pop(left_); |
| 979 } |
| 980 |
| 981 __ bind(&do_op); |
| 982 switch (op_) { |
| 983 case Token::ADD: __ addsd(xmm0, xmm1); break; |
| 984 case Token::SUB: __ subsd(xmm0, xmm1); break; |
| 985 case Token::MUL: __ mulsd(xmm0, xmm1); break; |
| 986 case Token::DIV: __ divsd(xmm0, xmm1); break; |
| 987 default: UNREACHABLE(); |
| 988 } |
| 955 } | 989 } |
| 956 __ movdbl(FieldOperand(dst_, HeapNumber::kValueOffset), xmm0); | 990 __ movdbl(FieldOperand(dst_, HeapNumber::kValueOffset), xmm0); |
| 957 __ jmp(&done); | 991 __ jmp(&done); |
| 958 | 992 |
| 959 __ bind(&after_alloc_failure); | 993 __ bind(&after_alloc_failure); |
| 960 __ pop(left_); | 994 __ pop(left_); |
| 961 __ bind(&call_runtime); | 995 __ bind(&call_runtime); |
| 962 } | 996 } |
| 963 GenericBinaryOpStub stub(op_, mode_, NO_SMI_CODE_IN_STUB); | 997 GenericBinaryOpStub stub(op_, mode_, NO_SMI_CODE_IN_STUB); |
| 964 stub.GenerateCall(masm_, left_, right_); | 998 stub.GenerateCall(masm_, left_, right_); |
| (...skipping 10050 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11015 | 11049 |
| 11016 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 11050 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
| 11017 // tagged as a small integer. | 11051 // tagged as a small integer. |
| 11018 __ bind(&runtime); | 11052 __ bind(&runtime); |
| 11019 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 11053 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
| 11020 } | 11054 } |
| 11021 | 11055 |
| 11022 #undef __ | 11056 #undef __ |
| 11023 | 11057 |
| 11024 } } // namespace v8::internal | 11058 } } // namespace v8::internal |
| OLD | NEW |