| 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 3627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3638 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { | 3638 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { |
| 3639 ASSERT(ToRegister(instr->result()).is(eax)); | 3639 ASSERT(ToRegister(instr->result()).is(eax)); |
| 3640 CallKnownFunction(instr->function(), | 3640 CallKnownFunction(instr->function(), |
| 3641 instr->arity(), | 3641 instr->arity(), |
| 3642 instr, | 3642 instr, |
| 3643 CALL_AS_METHOD, | 3643 CALL_AS_METHOD, |
| 3644 EDI_UNINITIALIZED); | 3644 EDI_UNINITIALIZED); |
| 3645 } | 3645 } |
| 3646 | 3646 |
| 3647 | 3647 |
| 3648 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { | 3648 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { |
| 3649 Register input_reg = ToRegister(instr->value()); | 3649 Register input_reg = ToRegister(instr->value()); |
| 3650 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), | 3650 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), |
| 3651 factory()->heap_number_map()); | 3651 factory()->heap_number_map()); |
| 3652 DeoptimizeIf(not_equal, instr->environment()); | 3652 DeoptimizeIf(not_equal, instr->environment()); |
| 3653 | 3653 |
| 3654 Label done; | 3654 Label done; |
| 3655 Register tmp = input_reg.is(eax) ? ecx : eax; | 3655 Register tmp = input_reg.is(eax) ? ecx : eax; |
| 3656 Register tmp2 = tmp.is(ecx) ? edx : input_reg.is(ecx) ? edx : ecx; | 3656 Register tmp2 = tmp.is(ecx) ? edx : input_reg.is(ecx) ? edx : ecx; |
| 3657 | 3657 |
| 3658 // Preserve the value of all registers. | 3658 // Preserve the value of all registers. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3691 __ and_(tmp2, ~HeapNumber::kSignMask); | 3691 __ and_(tmp2, ~HeapNumber::kSignMask); |
| 3692 __ mov(FieldOperand(tmp, HeapNumber::kExponentOffset), tmp2); | 3692 __ mov(FieldOperand(tmp, HeapNumber::kExponentOffset), tmp2); |
| 3693 __ mov(tmp2, FieldOperand(input_reg, HeapNumber::kMantissaOffset)); | 3693 __ mov(tmp2, FieldOperand(input_reg, HeapNumber::kMantissaOffset)); |
| 3694 __ mov(FieldOperand(tmp, HeapNumber::kMantissaOffset), tmp2); | 3694 __ mov(FieldOperand(tmp, HeapNumber::kMantissaOffset), tmp2); |
| 3695 __ StoreToSafepointRegisterSlot(input_reg, tmp); | 3695 __ StoreToSafepointRegisterSlot(input_reg, tmp); |
| 3696 | 3696 |
| 3697 __ bind(&done); | 3697 __ bind(&done); |
| 3698 } | 3698 } |
| 3699 | 3699 |
| 3700 | 3700 |
| 3701 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { | 3701 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) { |
| 3702 Register input_reg = ToRegister(instr->value()); | 3702 Register input_reg = ToRegister(instr->value()); |
| 3703 __ test(input_reg, Operand(input_reg)); | 3703 __ test(input_reg, Operand(input_reg)); |
| 3704 Label is_positive; | 3704 Label is_positive; |
| 3705 __ j(not_sign, &is_positive); | 3705 __ j(not_sign, &is_positive); |
| 3706 __ neg(input_reg); | 3706 __ neg(input_reg); |
| 3707 __ test(input_reg, Operand(input_reg)); | 3707 __ test(input_reg, Operand(input_reg)); |
| 3708 DeoptimizeIf(negative, instr->environment()); | 3708 DeoptimizeIf(negative, instr->environment()); |
| 3709 __ bind(&is_positive); | 3709 __ bind(&is_positive); |
| 3710 } | 3710 } |
| 3711 | 3711 |
| 3712 | 3712 |
| 3713 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { | 3713 void LCodeGen::DoMathAbs(LMathAbs* instr) { |
| 3714 // Class for deferred case. | 3714 // Class for deferred case. |
| 3715 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { | 3715 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { |
| 3716 public: | 3716 public: |
| 3717 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, | 3717 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr) |
| 3718 LUnaryMathOperation* instr) | |
| 3719 : LDeferredCode(codegen), instr_(instr) { } | 3718 : LDeferredCode(codegen), instr_(instr) { } |
| 3720 virtual void Generate() { | 3719 virtual void Generate() { |
| 3721 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); | 3720 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); |
| 3722 } | 3721 } |
| 3723 virtual LInstruction* instr() { return instr_; } | 3722 virtual LInstruction* instr() { return instr_; } |
| 3724 private: | 3723 private: |
| 3725 LUnaryMathOperation* instr_; | 3724 LMathAbs* instr_; |
| 3726 }; | 3725 }; |
| 3727 | 3726 |
| 3728 ASSERT(instr->value()->Equals(instr->result())); | 3727 ASSERT(instr->value()->Equals(instr->result())); |
| 3729 Representation r = instr->hydrogen()->value()->representation(); | 3728 Representation r = instr->hydrogen()->value()->representation(); |
| 3730 | 3729 |
| 3731 CpuFeatureScope scope(masm(), SSE2); | 3730 CpuFeatureScope scope(masm(), SSE2); |
| 3732 if (r.IsDouble()) { | 3731 if (r.IsDouble()) { |
| 3733 XMMRegister scratch = xmm0; | 3732 XMMRegister scratch = xmm0; |
| 3734 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 3733 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
| 3735 __ xorps(scratch, scratch); | 3734 __ xorps(scratch, scratch); |
| 3736 __ subsd(scratch, input_reg); | 3735 __ subsd(scratch, input_reg); |
| 3737 __ pand(input_reg, scratch); | 3736 __ pand(input_reg, scratch); |
| 3738 } else if (r.IsInteger32()) { | 3737 } else if (r.IsInteger32()) { |
| 3739 EmitIntegerMathAbs(instr); | 3738 EmitIntegerMathAbs(instr); |
| 3740 } else { // Tagged case. | 3739 } else { // Tagged case. |
| 3741 DeferredMathAbsTaggedHeapNumber* deferred = | 3740 DeferredMathAbsTaggedHeapNumber* deferred = |
| 3742 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr); | 3741 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr); |
| 3743 Register input_reg = ToRegister(instr->value()); | 3742 Register input_reg = ToRegister(instr->value()); |
| 3744 // Smi check. | 3743 // Smi check. |
| 3745 __ JumpIfNotSmi(input_reg, deferred->entry()); | 3744 __ JumpIfNotSmi(input_reg, deferred->entry()); |
| 3746 EmitIntegerMathAbs(instr); | 3745 EmitIntegerMathAbs(instr); |
| 3747 __ bind(deferred->exit()); | 3746 __ bind(deferred->exit()); |
| 3748 } | 3747 } |
| 3749 } | 3748 } |
| 3750 | 3749 |
| 3751 | 3750 |
| 3752 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { | 3751 void LCodeGen::DoMathFloor(LMathFloor* instr) { |
| 3753 CpuFeatureScope scope(masm(), SSE2); | 3752 CpuFeatureScope scope(masm(), SSE2); |
| 3754 XMMRegister xmm_scratch = xmm0; | 3753 XMMRegister xmm_scratch = xmm0; |
| 3755 Register output_reg = ToRegister(instr->result()); | 3754 Register output_reg = ToRegister(instr->result()); |
| 3756 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 3755 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
| 3757 | 3756 |
| 3758 if (CpuFeatures::IsSupported(SSE4_1)) { | 3757 if (CpuFeatures::IsSupported(SSE4_1)) { |
| 3759 CpuFeatureScope scope(masm(), SSE4_1); | 3758 CpuFeatureScope scope(masm(), SSE4_1); |
| 3760 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 3759 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 3761 // Deoptimize on negative zero. | 3760 // Deoptimize on negative zero. |
| 3762 Label non_zero; | 3761 Label non_zero; |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3868 __ movmskpd(output_reg, input_reg); | 3867 __ movmskpd(output_reg, input_reg); |
| 3869 __ test(output_reg, Immediate(1)); | 3868 __ test(output_reg, Immediate(1)); |
| 3870 __ RecordComment("Minus zero"); | 3869 __ RecordComment("Minus zero"); |
| 3871 DeoptimizeIf(not_zero, instr->environment()); | 3870 DeoptimizeIf(not_zero, instr->environment()); |
| 3872 } | 3871 } |
| 3873 __ Set(output_reg, Immediate(0)); | 3872 __ Set(output_reg, Immediate(0)); |
| 3874 __ bind(&done); | 3873 __ bind(&done); |
| 3875 } | 3874 } |
| 3876 | 3875 |
| 3877 | 3876 |
| 3878 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { | 3877 void LCodeGen::DoMathSqrt(LMathSqrt* instr) { |
| 3879 CpuFeatureScope scope(masm(), SSE2); | 3878 CpuFeatureScope scope(masm(), SSE2); |
| 3880 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 3879 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
| 3881 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); | 3880 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); |
| 3882 __ sqrtsd(input_reg, input_reg); | 3881 __ sqrtsd(input_reg, input_reg); |
| 3883 } | 3882 } |
| 3884 | 3883 |
| 3885 | 3884 |
| 3886 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) { | 3885 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) { |
| 3887 CpuFeatureScope scope(masm(), SSE2); | 3886 CpuFeatureScope scope(masm(), SSE2); |
| 3888 XMMRegister xmm_scratch = xmm0; | 3887 XMMRegister xmm_scratch = xmm0; |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4021 | 4020 |
| 4022 | 4021 |
| 4023 void LCodeGen::DoDeferredRandom(LRandom* instr) { | 4022 void LCodeGen::DoDeferredRandom(LRandom* instr) { |
| 4024 __ PrepareCallCFunction(1, ebx); | 4023 __ PrepareCallCFunction(1, ebx); |
| 4025 __ mov(Operand(esp, 0), eax); | 4024 __ mov(Operand(esp, 0), eax); |
| 4026 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); | 4025 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); |
| 4027 // Return value is in eax. | 4026 // Return value is in eax. |
| 4028 } | 4027 } |
| 4029 | 4028 |
| 4030 | 4029 |
| 4031 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) { | 4030 void LCodeGen::DoMathLog(LMathLog* instr) { |
| 4032 CpuFeatureScope scope(masm(), SSE2); | 4031 CpuFeatureScope scope(masm(), SSE2); |
| 4033 ASSERT(instr->value()->Equals(instr->result())); | 4032 ASSERT(instr->value()->Equals(instr->result())); |
| 4034 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 4033 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
| 4035 Label positive, done, zero; | 4034 Label positive, done, zero; |
| 4036 __ xorps(xmm0, xmm0); | 4035 __ xorps(xmm0, xmm0); |
| 4037 __ ucomisd(input_reg, xmm0); | 4036 __ ucomisd(input_reg, xmm0); |
| 4038 __ j(above, &positive, Label::kNear); | 4037 __ j(above, &positive, Label::kNear); |
| 4039 __ j(equal, &zero, Label::kNear); | 4038 __ j(equal, &zero, Label::kNear); |
| 4040 ExternalReference nan = | 4039 ExternalReference nan = |
| 4041 ExternalReference::address_of_canonical_non_hole_nan(); | 4040 ExternalReference::address_of_canonical_non_hole_nan(); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 4064 CpuFeatureScope scope(masm(), SSE2); | 4063 CpuFeatureScope scope(masm(), SSE2); |
| 4065 XMMRegister input = ToDoubleRegister(instr->value()); | 4064 XMMRegister input = ToDoubleRegister(instr->value()); |
| 4066 XMMRegister result = ToDoubleRegister(instr->result()); | 4065 XMMRegister result = ToDoubleRegister(instr->result()); |
| 4067 Register temp1 = ToRegister(instr->temp1()); | 4066 Register temp1 = ToRegister(instr->temp1()); |
| 4068 Register temp2 = ToRegister(instr->temp2()); | 4067 Register temp2 = ToRegister(instr->temp2()); |
| 4069 | 4068 |
| 4070 MathExpGenerator::EmitMathExp(masm(), input, result, xmm0, temp1, temp2); | 4069 MathExpGenerator::EmitMathExp(masm(), input, result, xmm0, temp1, temp2); |
| 4071 } | 4070 } |
| 4072 | 4071 |
| 4073 | 4072 |
| 4074 void LCodeGen::DoMathTan(LUnaryMathOperation* instr) { | 4073 void LCodeGen::DoMathTan(LMathTan* instr) { |
| 4075 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); | 4074 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); |
| 4076 TranscendentalCacheStub stub(TranscendentalCache::TAN, | 4075 TranscendentalCacheStub stub(TranscendentalCache::TAN, |
| 4077 TranscendentalCacheStub::UNTAGGED); | 4076 TranscendentalCacheStub::UNTAGGED); |
| 4078 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 4077 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 4079 } | 4078 } |
| 4080 | 4079 |
| 4081 | 4080 |
| 4082 void LCodeGen::DoMathCos(LUnaryMathOperation* instr) { | 4081 void LCodeGen::DoMathCos(LMathCos* instr) { |
| 4083 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); | 4082 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); |
| 4084 TranscendentalCacheStub stub(TranscendentalCache::COS, | 4083 TranscendentalCacheStub stub(TranscendentalCache::COS, |
| 4085 TranscendentalCacheStub::UNTAGGED); | 4084 TranscendentalCacheStub::UNTAGGED); |
| 4086 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 4085 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 4087 } | 4086 } |
| 4088 | 4087 |
| 4089 | 4088 |
| 4090 void LCodeGen::DoMathSin(LUnaryMathOperation* instr) { | 4089 void LCodeGen::DoMathSin(LMathSin* instr) { |
| 4091 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); | 4090 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); |
| 4092 TranscendentalCacheStub stub(TranscendentalCache::SIN, | 4091 TranscendentalCacheStub stub(TranscendentalCache::SIN, |
| 4093 TranscendentalCacheStub::UNTAGGED); | 4092 TranscendentalCacheStub::UNTAGGED); |
| 4094 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 4093 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 4095 } | 4094 } |
| 4096 | 4095 |
| 4097 | 4096 |
| 4098 void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) { | |
| 4099 switch (instr->op()) { | |
| 4100 case kMathAbs: | |
| 4101 DoMathAbs(instr); | |
| 4102 break; | |
| 4103 case kMathFloor: | |
| 4104 DoMathFloor(instr); | |
| 4105 break; | |
| 4106 case kMathSqrt: | |
| 4107 DoMathSqrt(instr); | |
| 4108 break; | |
| 4109 case kMathCos: | |
| 4110 DoMathCos(instr); | |
| 4111 break; | |
| 4112 case kMathSin: | |
| 4113 DoMathSin(instr); | |
| 4114 break; | |
| 4115 case kMathTan: | |
| 4116 DoMathTan(instr); | |
| 4117 break; | |
| 4118 case kMathLog: | |
| 4119 DoMathLog(instr); | |
| 4120 break; | |
| 4121 | |
| 4122 default: | |
| 4123 UNREACHABLE(); | |
| 4124 } | |
| 4125 } | |
| 4126 | |
| 4127 | |
| 4128 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { | 4097 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { |
| 4129 ASSERT(ToRegister(instr->context()).is(esi)); | 4098 ASSERT(ToRegister(instr->context()).is(esi)); |
| 4130 ASSERT(ToRegister(instr->function()).is(edi)); | 4099 ASSERT(ToRegister(instr->function()).is(edi)); |
| 4131 ASSERT(instr->HasPointerMap()); | 4100 ASSERT(instr->HasPointerMap()); |
| 4132 | 4101 |
| 4133 if (instr->known_function().is_null()) { | 4102 if (instr->known_function().is_null()) { |
| 4134 LPointerMap* pointers = instr->pointer_map(); | 4103 LPointerMap* pointers = instr->pointer_map(); |
| 4135 RecordPosition(pointers->position()); | 4104 RecordPosition(pointers->position()); |
| 4136 SafepointGenerator generator( | 4105 SafepointGenerator generator( |
| 4137 this, pointers, Safepoint::kLazyDeopt); | 4106 this, pointers, Safepoint::kLazyDeopt); |
| (...skipping 2436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6574 FixedArray::kHeaderSize - kPointerSize)); | 6543 FixedArray::kHeaderSize - kPointerSize)); |
| 6575 __ bind(&done); | 6544 __ bind(&done); |
| 6576 } | 6545 } |
| 6577 | 6546 |
| 6578 | 6547 |
| 6579 #undef __ | 6548 #undef __ |
| 6580 | 6549 |
| 6581 } } // namespace v8::internal | 6550 } } // namespace v8::internal |
| 6582 | 6551 |
| 6583 #endif // V8_TARGET_ARCH_IA32 | 6552 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |