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 4032 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4043 __ CompareRoot(FieldOperand(exponent.reg(), HeapObject::kMapOffset), | 4043 __ CompareRoot(FieldOperand(exponent.reg(), HeapObject::kMapOffset), |
4044 Heap::kHeapNumberMapRootIndex); | 4044 Heap::kHeapNumberMapRootIndex); |
4045 call_runtime.Branch(not_equal); | 4045 call_runtime.Branch(not_equal); |
4046 __ movsd(xmm1, FieldOperand(exponent.reg(), HeapNumber::kValueOffset)); | 4046 __ movsd(xmm1, FieldOperand(exponent.reg(), HeapNumber::kValueOffset)); |
4047 // Test if exponent is nan. | 4047 // Test if exponent is nan. |
4048 __ ucomisd(xmm1, xmm1); | 4048 __ ucomisd(xmm1, xmm1); |
4049 call_runtime.Branch(parity_even); | 4049 call_runtime.Branch(parity_even); |
4050 | 4050 |
4051 Label base_not_smi; | 4051 Label base_not_smi; |
4052 Label handle_special_cases; | 4052 Label handle_special_cases; |
4053 __ testl(base.reg(), Immediate(kSmiTagMask)); | 4053 __ JumpIfNotSmi(base.reg(), &base_not_smi); |
4054 __ j(not_zero, &base_not_smi); | |
4055 __ SmiToInteger32(base.reg(), base.reg()); | 4054 __ SmiToInteger32(base.reg(), base.reg()); |
4056 __ cvtlsi2sd(xmm0, base.reg()); | 4055 __ cvtlsi2sd(xmm0, base.reg()); |
4057 __ jmp(&handle_special_cases); | 4056 __ jmp(&handle_special_cases); |
4058 __ bind(&base_not_smi); | 4057 __ bind(&base_not_smi); |
4059 __ CompareRoot(FieldOperand(base.reg(), HeapObject::kMapOffset), | 4058 __ CompareRoot(FieldOperand(base.reg(), HeapObject::kMapOffset), |
4060 Heap::kHeapNumberMapRootIndex); | 4059 Heap::kHeapNumberMapRootIndex); |
4061 call_runtime.Branch(not_equal); | 4060 call_runtime.Branch(not_equal); |
4062 __ movl(answer.reg(), FieldOperand(base.reg(), HeapNumber::kExponentOffset)); | 4061 __ movl(answer.reg(), FieldOperand(base.reg(), HeapNumber::kExponentOffset)); |
4063 __ andl(answer.reg(), Immediate(HeapNumber::kExponentMask)); | 4062 __ andl(answer.reg(), Immediate(HeapNumber::kExponentMask)); |
4064 __ cmpl(answer.reg(), Immediate(HeapNumber::kExponentMask)); | 4063 __ cmpl(answer.reg(), Immediate(HeapNumber::kExponentMask)); |
(...skipping 1823 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5888 private: | 5887 private: |
5889 Token::Value op_; | 5888 Token::Value op_; |
5890 Register dst_; | 5889 Register dst_; |
5891 Register left_; | 5890 Register left_; |
5892 Register right_; | 5891 Register right_; |
5893 OverwriteMode mode_; | 5892 OverwriteMode mode_; |
5894 }; | 5893 }; |
5895 | 5894 |
5896 | 5895 |
5897 void DeferredInlineBinaryOperation::Generate() { | 5896 void DeferredInlineBinaryOperation::Generate() { |
5897 Label done; | |
5898 if ((op_ == Token::ADD) | |
5899 || (op_ ==Token::SUB) | |
5900 || (op_ == Token::MUL) | |
5901 || (op_ == Token::DIV)) { | |
5902 Label call_runtime, after_alloc_failure; | |
5903 Label left_smi, right_smi, load_right, do_op; | |
5904 __ JumpIfSmi(left_, &left_smi); | |
5905 __ CompareRoot(FieldOperand(left_, HeapObject::kMapOffset), | |
5906 Heap::kHeapNumberMapRootIndex); | |
5907 __ j(not_equal, &call_runtime); | |
5908 __ movsd(xmm0, FieldOperand(left_, HeapNumber::kValueOffset)); | |
5909 if (mode_ == OVERWRITE_LEFT) { | |
5910 __ movq(dst_, left_); | |
5911 } | |
5912 __ jmp(&load_right); | |
5913 | |
5914 __ bind(&left_smi); | |
5915 __ SmiToInteger32(left_, left_); | |
Lasse Reichstein
2010/04/29 12:36:40
If you have a spare register here, you could conve
Mads Ager (chromium)
2010/05/03 08:47:09
I can convert the smi into an integer in kScratchR
| |
5916 __ cvtlsi2sd(xmm0, left_); | |
5917 __ Integer32ToSmi(left_, left_); | |
5918 if (mode_ == OVERWRITE_LEFT) { | |
5919 Label alloc_failure; | |
5920 __ push(left_); | |
5921 __ AllocateHeapNumber(dst_, left_, &after_alloc_failure); | |
Lasse Reichstein
2010/04/29 12:36:40
I'll bet I can make a version of AllocateHeapNumbe
| |
5922 __ pop(left_); | |
5923 } | |
5924 | |
5925 __ bind(&load_right); | |
5926 __ JumpIfSmi(right_, &right_smi); | |
5927 __ CompareRoot(FieldOperand(right_, HeapObject::kMapOffset), | |
5928 Heap::kHeapNumberMapRootIndex); | |
5929 __ j(not_equal, &call_runtime); | |
5930 __ movsd(xmm1, FieldOperand(right_, HeapNumber::kValueOffset)); | |
5931 if (mode_ == OVERWRITE_RIGHT) { | |
5932 __ movq(dst_, right_); | |
5933 } else if (mode_ == NO_OVERWRITE) { | |
5934 Label alloc_failure; | |
5935 __ push(left_); | |
5936 __ AllocateHeapNumber(dst_, left_, &after_alloc_failure); | |
5937 __ pop(left_); | |
5938 } | |
5939 __ jmp(&do_op); | |
5940 | |
5941 __ bind(&right_smi); | |
5942 __ SmiToInteger32(right_, right_); | |
5943 __ cvtlsi2sd(xmm1, right_); | |
5944 __ Integer32ToSmi(right_, right_); | |
5945 if (mode_ == OVERWRITE_RIGHT || mode_ == NO_OVERWRITE) { | |
5946 Label alloc_failure; | |
5947 __ push(left_); | |
5948 __ AllocateHeapNumber(dst_, left_, &after_alloc_failure); | |
5949 __ pop(left_); | |
5950 } | |
5951 | |
5952 __ bind(&do_op); | |
5953 switch (op_) { | |
5954 case Token::ADD: __ addsd(xmm0, xmm1); break; | |
5955 case Token::SUB: __ subsd(xmm0, xmm1); break; | |
5956 case Token::MUL: __ mulsd(xmm0, xmm1); break; | |
5957 case Token::DIV: __ divsd(xmm0, xmm1); break; | |
5958 default: UNREACHABLE(); | |
5959 } | |
5960 __ movsd(FieldOperand(dst_, HeapNumber::kValueOffset), xmm0); | |
5961 __ jmp(&done); | |
5962 | |
5963 __ bind(&after_alloc_failure); | |
5964 __ pop(left_); | |
5965 __ bind(&call_runtime); | |
5966 } | |
5898 GenericBinaryOpStub stub(op_, mode_, NO_SMI_CODE_IN_STUB); | 5967 GenericBinaryOpStub stub(op_, mode_, NO_SMI_CODE_IN_STUB); |
5899 stub.GenerateCall(masm_, left_, right_); | 5968 stub.GenerateCall(masm_, left_, right_); |
5900 if (!dst_.is(rax)) __ movq(dst_, rax); | 5969 if (!dst_.is(rax)) __ movq(dst_, rax); |
5970 __ bind(&done); | |
5901 } | 5971 } |
5902 | 5972 |
5903 | 5973 |
5904 static TypeInfo CalculateTypeInfo(TypeInfo operands_type, | 5974 static TypeInfo CalculateTypeInfo(TypeInfo operands_type, |
5905 Token::Value op, | 5975 Token::Value op, |
5906 const Result& right, | 5976 const Result& right, |
5907 const Result& left) { | 5977 const Result& left) { |
5908 // Set TypeInfo of result according to the operation performed. | 5978 // Set TypeInfo of result according to the operation performed. |
5909 // We rely on the fact that smis have a 32 bit payload on x64. | 5979 // We rely on the fact that smis have a 32 bit payload on x64. |
5910 STATIC_ASSERT(kSmiValueSize == 32); | 5980 STATIC_ASSERT(kSmiValueSize == 32); |
(...skipping 4966 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10877 // Call the function from C++. | 10947 // Call the function from C++. |
10878 return FUNCTION_CAST<ModuloFunction>(buffer); | 10948 return FUNCTION_CAST<ModuloFunction>(buffer); |
10879 } | 10949 } |
10880 | 10950 |
10881 #endif | 10951 #endif |
10882 | 10952 |
10883 | 10953 |
10884 #undef __ | 10954 #undef __ |
10885 | 10955 |
10886 } } // namespace v8::internal | 10956 } } // namespace v8::internal |
OLD | NEW |