Chromium Code Reviews| 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 |