| 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 3429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3440 ASSERT(ToRegister(instr->result()).is(v0)); | 3440 ASSERT(ToRegister(instr->result()).is(v0)); |
| 3441 __ mov(a0, v0); | 3441 __ mov(a0, v0); |
| 3442 CallKnownFunction(instr->function(), | 3442 CallKnownFunction(instr->function(), |
| 3443 instr->arity(), | 3443 instr->arity(), |
| 3444 instr, | 3444 instr, |
| 3445 CALL_AS_METHOD, | 3445 CALL_AS_METHOD, |
| 3446 A1_UNINITIALIZED); | 3446 A1_UNINITIALIZED); |
| 3447 } | 3447 } |
| 3448 | 3448 |
| 3449 | 3449 |
| 3450 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { | 3450 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { |
| 3451 Register input = ToRegister(instr->value()); | 3451 Register input = ToRegister(instr->value()); |
| 3452 Register result = ToRegister(instr->result()); | 3452 Register result = ToRegister(instr->result()); |
| 3453 Register scratch = scratch0(); | 3453 Register scratch = scratch0(); |
| 3454 | 3454 |
| 3455 // Deoptimize if not a heap number. | 3455 // Deoptimize if not a heap number. |
| 3456 __ lw(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); | 3456 __ lw(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); |
| 3457 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); | 3457 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); |
| 3458 DeoptimizeIf(ne, instr->environment(), scratch, Operand(at)); | 3458 DeoptimizeIf(ne, instr->environment(), scratch, Operand(at)); |
| 3459 | 3459 |
| 3460 Label done; | 3460 Label done; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3505 __ lw(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset)); | 3505 __ lw(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset)); |
| 3506 __ sw(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset)); | 3506 __ sw(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset)); |
| 3507 | 3507 |
| 3508 __ StoreToSafepointRegisterSlot(tmp1, result); | 3508 __ StoreToSafepointRegisterSlot(tmp1, result); |
| 3509 } | 3509 } |
| 3510 | 3510 |
| 3511 __ bind(&done); | 3511 __ bind(&done); |
| 3512 } | 3512 } |
| 3513 | 3513 |
| 3514 | 3514 |
| 3515 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { | 3515 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) { |
| 3516 Register input = ToRegister(instr->value()); | 3516 Register input = ToRegister(instr->value()); |
| 3517 Register result = ToRegister(instr->result()); | 3517 Register result = ToRegister(instr->result()); |
| 3518 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); | 3518 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); |
| 3519 Label done; | 3519 Label done; |
| 3520 __ Branch(USE_DELAY_SLOT, &done, ge, input, Operand(zero_reg)); | 3520 __ Branch(USE_DELAY_SLOT, &done, ge, input, Operand(zero_reg)); |
| 3521 __ mov(result, input); | 3521 __ mov(result, input); |
| 3522 // Overflow if result is still negative, i.e. 0x80000000. | 3522 // Overflow if result is still negative, i.e. 0x80000000. |
| 3523 DeoptimizeIf(lt, instr->environment(), result, Operand(zero_reg)); | 3523 DeoptimizeIf(lt, instr->environment(), result, Operand(zero_reg)); |
| 3524 __ bind(&done); | 3524 __ bind(&done); |
| 3525 } | 3525 } |
| 3526 | 3526 |
| 3527 | 3527 |
| 3528 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { | 3528 void LCodeGen::DoMathAbs(LMathAbs* instr) { |
| 3529 CpuFeatureScope scope(masm(), FPU); | 3529 CpuFeatureScope scope(masm(), FPU); |
| 3530 // Class for deferred case. | 3530 // Class for deferred case. |
| 3531 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { | 3531 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { |
| 3532 public: | 3532 public: |
| 3533 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, | 3533 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr) |
| 3534 LUnaryMathOperation* instr) | |
| 3535 : LDeferredCode(codegen), instr_(instr) { } | 3534 : LDeferredCode(codegen), instr_(instr) { } |
| 3536 virtual void Generate() { | 3535 virtual void Generate() { |
| 3537 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); | 3536 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); |
| 3538 } | 3537 } |
| 3539 virtual LInstruction* instr() { return instr_; } | 3538 virtual LInstruction* instr() { return instr_; } |
| 3540 private: | 3539 private: |
| 3541 LUnaryMathOperation* instr_; | 3540 LMathAbs* instr_; |
| 3542 }; | 3541 }; |
| 3543 | 3542 |
| 3544 Representation r = instr->hydrogen()->value()->representation(); | 3543 Representation r = instr->hydrogen()->value()->representation(); |
| 3545 if (r.IsDouble()) { | 3544 if (r.IsDouble()) { |
| 3546 FPURegister input = ToDoubleRegister(instr->value()); | 3545 FPURegister input = ToDoubleRegister(instr->value()); |
| 3547 FPURegister result = ToDoubleRegister(instr->result()); | 3546 FPURegister result = ToDoubleRegister(instr->result()); |
| 3548 __ abs_d(result, input); | 3547 __ abs_d(result, input); |
| 3549 } else if (r.IsInteger32()) { | 3548 } else if (r.IsInteger32()) { |
| 3550 EmitIntegerMathAbs(instr); | 3549 EmitIntegerMathAbs(instr); |
| 3551 } else { | 3550 } else { |
| 3552 // Representation is tagged. | 3551 // Representation is tagged. |
| 3553 DeferredMathAbsTaggedHeapNumber* deferred = | 3552 DeferredMathAbsTaggedHeapNumber* deferred = |
| 3554 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr); | 3553 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr); |
| 3555 Register input = ToRegister(instr->value()); | 3554 Register input = ToRegister(instr->value()); |
| 3556 // Smi check. | 3555 // Smi check. |
| 3557 __ JumpIfNotSmi(input, deferred->entry()); | 3556 __ JumpIfNotSmi(input, deferred->entry()); |
| 3558 // If smi, handle it directly. | 3557 // If smi, handle it directly. |
| 3559 EmitIntegerMathAbs(instr); | 3558 EmitIntegerMathAbs(instr); |
| 3560 __ bind(deferred->exit()); | 3559 __ bind(deferred->exit()); |
| 3561 } | 3560 } |
| 3562 } | 3561 } |
| 3563 | 3562 |
| 3564 | 3563 |
| 3565 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { | 3564 void LCodeGen::DoMathFloor(LMathFloor* instr) { |
| 3566 CpuFeatureScope scope(masm(), FPU); | 3565 CpuFeatureScope scope(masm(), FPU); |
| 3567 DoubleRegister input = ToDoubleRegister(instr->value()); | 3566 DoubleRegister input = ToDoubleRegister(instr->value()); |
| 3568 Register result = ToRegister(instr->result()); | 3567 Register result = ToRegister(instr->result()); |
| 3569 Register scratch1 = scratch0(); | 3568 Register scratch1 = scratch0(); |
| 3570 Register except_flag = ToRegister(instr->temp()); | 3569 Register except_flag = ToRegister(instr->temp()); |
| 3571 | 3570 |
| 3572 __ EmitFPUTruncate(kRoundToMinusInf, | 3571 __ EmitFPUTruncate(kRoundToMinusInf, |
| 3573 result, | 3572 result, |
| 3574 input, | 3573 input, |
| 3575 scratch1, | 3574 scratch1, |
| 3576 double_scratch0(), | 3575 double_scratch0(), |
| 3577 except_flag); | 3576 except_flag); |
| 3578 | 3577 |
| 3579 // Deopt if the operation did not succeed. | 3578 // Deopt if the operation did not succeed. |
| 3580 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); | 3579 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); |
| 3581 | 3580 |
| 3582 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 3581 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 3583 // Test for -0. | 3582 // Test for -0. |
| 3584 Label done; | 3583 Label done; |
| 3585 __ Branch(&done, ne, result, Operand(zero_reg)); | 3584 __ Branch(&done, ne, result, Operand(zero_reg)); |
| 3586 __ mfc1(scratch1, input.high()); | 3585 __ mfc1(scratch1, input.high()); |
| 3587 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); | 3586 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); |
| 3588 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); | 3587 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); |
| 3589 __ bind(&done); | 3588 __ bind(&done); |
| 3590 } | 3589 } |
| 3591 } | 3590 } |
| 3592 | 3591 |
| 3593 | 3592 |
| 3594 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { | 3593 void LCodeGen::DoMathRound(LMathRound* instr) { |
| 3595 CpuFeatureScope scope(masm(), FPU); | 3594 CpuFeatureScope scope(masm(), FPU); |
| 3596 DoubleRegister input = ToDoubleRegister(instr->value()); | 3595 DoubleRegister input = ToDoubleRegister(instr->value()); |
| 3597 Register result = ToRegister(instr->result()); | 3596 Register result = ToRegister(instr->result()); |
| 3598 DoubleRegister double_scratch1 = ToDoubleRegister(instr->temp()); | 3597 DoubleRegister double_scratch1 = ToDoubleRegister(instr->temp()); |
| 3599 Register scratch = scratch0(); | 3598 Register scratch = scratch0(); |
| 3600 Label done, check_sign_on_zero; | 3599 Label done, check_sign_on_zero; |
| 3601 | 3600 |
| 3602 // Extract exponent bits. | 3601 // Extract exponent bits. |
| 3603 __ mfc1(result, input.high()); | 3602 __ mfc1(result, input.high()); |
| 3604 __ Ext(scratch, | 3603 __ Ext(scratch, |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3661 __ Branch(&done, ne, result, Operand(zero_reg)); | 3660 __ Branch(&done, ne, result, Operand(zero_reg)); |
| 3662 __ bind(&check_sign_on_zero); | 3661 __ bind(&check_sign_on_zero); |
| 3663 __ mfc1(scratch, input.high()); | 3662 __ mfc1(scratch, input.high()); |
| 3664 __ And(scratch, scratch, Operand(HeapNumber::kSignMask)); | 3663 __ And(scratch, scratch, Operand(HeapNumber::kSignMask)); |
| 3665 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); | 3664 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); |
| 3666 } | 3665 } |
| 3667 __ bind(&done); | 3666 __ bind(&done); |
| 3668 } | 3667 } |
| 3669 | 3668 |
| 3670 | 3669 |
| 3671 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { | 3670 void LCodeGen::DoMathSqrt(LMathSqrt* instr) { |
| 3672 CpuFeatureScope scope(masm(), FPU); | 3671 CpuFeatureScope scope(masm(), FPU); |
| 3673 DoubleRegister input = ToDoubleRegister(instr->value()); | 3672 DoubleRegister input = ToDoubleRegister(instr->value()); |
| 3674 DoubleRegister result = ToDoubleRegister(instr->result()); | 3673 DoubleRegister result = ToDoubleRegister(instr->result()); |
| 3675 __ sqrt_d(result, input); | 3674 __ sqrt_d(result, input); |
| 3676 } | 3675 } |
| 3677 | 3676 |
| 3678 | 3677 |
| 3679 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { | 3678 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) { |
| 3680 CpuFeatureScope scope(masm(), FPU); | 3679 CpuFeatureScope scope(masm(), FPU); |
| 3681 DoubleRegister input = ToDoubleRegister(instr->value()); | 3680 DoubleRegister input = ToDoubleRegister(instr->value()); |
| 3682 DoubleRegister result = ToDoubleRegister(instr->result()); | 3681 DoubleRegister result = ToDoubleRegister(instr->result()); |
| 3683 DoubleRegister temp = ToDoubleRegister(instr->temp()); | 3682 DoubleRegister temp = ToDoubleRegister(instr->temp()); |
| 3684 | 3683 |
| 3685 ASSERT(!input.is(result)); | 3684 ASSERT(!input.is(result)); |
| 3686 | 3685 |
| 3687 // Note that according to ECMA-262 15.8.2.13: | 3686 // Note that according to ECMA-262 15.8.2.13: |
| 3688 // Math.pow(-Infinity, 0.5) == Infinity | 3687 // Math.pow(-Infinity, 0.5) == Infinity |
| 3689 // Math.sqrt(-Infinity) == NaN | 3688 // Math.sqrt(-Infinity) == NaN |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3817 DoubleRegister double_scratch2 = double_scratch0(); | 3816 DoubleRegister double_scratch2 = double_scratch0(); |
| 3818 Register temp1 = ToRegister(instr->temp1()); | 3817 Register temp1 = ToRegister(instr->temp1()); |
| 3819 Register temp2 = ToRegister(instr->temp2()); | 3818 Register temp2 = ToRegister(instr->temp2()); |
| 3820 | 3819 |
| 3821 MathExpGenerator::EmitMathExp( | 3820 MathExpGenerator::EmitMathExp( |
| 3822 masm(), input, result, double_scratch1, double_scratch2, | 3821 masm(), input, result, double_scratch1, double_scratch2, |
| 3823 temp1, temp2, scratch0()); | 3822 temp1, temp2, scratch0()); |
| 3824 } | 3823 } |
| 3825 | 3824 |
| 3826 | 3825 |
| 3827 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) { | 3826 void LCodeGen::DoMathLog(LMathLog* instr) { |
| 3828 ASSERT(ToDoubleRegister(instr->result()).is(f4)); | 3827 ASSERT(ToDoubleRegister(instr->result()).is(f4)); |
| 3829 TranscendentalCacheStub stub(TranscendentalCache::LOG, | 3828 TranscendentalCacheStub stub(TranscendentalCache::LOG, |
| 3830 TranscendentalCacheStub::UNTAGGED); | 3829 TranscendentalCacheStub::UNTAGGED); |
| 3831 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 3830 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 3832 } | 3831 } |
| 3833 | 3832 |
| 3834 | 3833 |
| 3835 void LCodeGen::DoMathTan(LUnaryMathOperation* instr) { | 3834 void LCodeGen::DoMathTan(LMathTan* instr) { |
| 3836 ASSERT(ToDoubleRegister(instr->result()).is(f4)); | 3835 ASSERT(ToDoubleRegister(instr->result()).is(f4)); |
| 3837 TranscendentalCacheStub stub(TranscendentalCache::TAN, | 3836 TranscendentalCacheStub stub(TranscendentalCache::TAN, |
| 3838 TranscendentalCacheStub::UNTAGGED); | 3837 TranscendentalCacheStub::UNTAGGED); |
| 3839 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 3838 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 3840 } | 3839 } |
| 3841 | 3840 |
| 3842 | 3841 |
| 3843 void LCodeGen::DoMathCos(LUnaryMathOperation* instr) { | 3842 void LCodeGen::DoMathCos(LMathCos* instr) { |
| 3844 ASSERT(ToDoubleRegister(instr->result()).is(f4)); | 3843 ASSERT(ToDoubleRegister(instr->result()).is(f4)); |
| 3845 TranscendentalCacheStub stub(TranscendentalCache::COS, | 3844 TranscendentalCacheStub stub(TranscendentalCache::COS, |
| 3846 TranscendentalCacheStub::UNTAGGED); | 3845 TranscendentalCacheStub::UNTAGGED); |
| 3847 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 3846 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 3848 } | 3847 } |
| 3849 | 3848 |
| 3850 | 3849 |
| 3851 void LCodeGen::DoMathSin(LUnaryMathOperation* instr) { | 3850 void LCodeGen::DoMathSin(LMathSin* instr) { |
| 3852 ASSERT(ToDoubleRegister(instr->result()).is(f4)); | 3851 ASSERT(ToDoubleRegister(instr->result()).is(f4)); |
| 3853 TranscendentalCacheStub stub(TranscendentalCache::SIN, | 3852 TranscendentalCacheStub stub(TranscendentalCache::SIN, |
| 3854 TranscendentalCacheStub::UNTAGGED); | 3853 TranscendentalCacheStub::UNTAGGED); |
| 3855 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 3854 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 3856 } | 3855 } |
| 3857 | 3856 |
| 3858 | 3857 |
| 3859 void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) { | |
| 3860 switch (instr->op()) { | |
| 3861 case kMathAbs: | |
| 3862 DoMathAbs(instr); | |
| 3863 break; | |
| 3864 case kMathFloor: | |
| 3865 DoMathFloor(instr); | |
| 3866 break; | |
| 3867 case kMathRound: | |
| 3868 DoMathRound(instr); | |
| 3869 break; | |
| 3870 case kMathSqrt: | |
| 3871 DoMathSqrt(instr); | |
| 3872 break; | |
| 3873 case kMathPowHalf: | |
| 3874 DoMathPowHalf(instr); | |
| 3875 break; | |
| 3876 case kMathCos: | |
| 3877 DoMathCos(instr); | |
| 3878 break; | |
| 3879 case kMathSin: | |
| 3880 DoMathSin(instr); | |
| 3881 break; | |
| 3882 case kMathTan: | |
| 3883 DoMathTan(instr); | |
| 3884 break; | |
| 3885 case kMathLog: | |
| 3886 DoMathLog(instr); | |
| 3887 break; | |
| 3888 default: | |
| 3889 Abort("Unimplemented type of LUnaryMathOperation."); | |
| 3890 UNREACHABLE(); | |
| 3891 } | |
| 3892 } | |
| 3893 | |
| 3894 | |
| 3895 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { | 3858 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { |
| 3896 ASSERT(ToRegister(instr->function()).is(a1)); | 3859 ASSERT(ToRegister(instr->function()).is(a1)); |
| 3897 ASSERT(instr->HasPointerMap()); | 3860 ASSERT(instr->HasPointerMap()); |
| 3898 | 3861 |
| 3899 if (instr->known_function().is_null()) { | 3862 if (instr->known_function().is_null()) { |
| 3900 LPointerMap* pointers = instr->pointer_map(); | 3863 LPointerMap* pointers = instr->pointer_map(); |
| 3901 RecordPosition(pointers->position()); | 3864 RecordPosition(pointers->position()); |
| 3902 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); | 3865 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |
| 3903 ParameterCount count(instr->arity()); | 3866 ParameterCount count(instr->arity()); |
| 3904 __ InvokeFunction(a1, count, CALL_FUNCTION, generator, CALL_AS_METHOD); | 3867 __ InvokeFunction(a1, count, CALL_FUNCTION, generator, CALL_AS_METHOD); |
| (...skipping 2031 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5936 __ Subu(scratch, result, scratch); | 5899 __ Subu(scratch, result, scratch); |
| 5937 __ lw(result, FieldMemOperand(scratch, | 5900 __ lw(result, FieldMemOperand(scratch, |
| 5938 FixedArray::kHeaderSize - kPointerSize)); | 5901 FixedArray::kHeaderSize - kPointerSize)); |
| 5939 __ bind(&done); | 5902 __ bind(&done); |
| 5940 } | 5903 } |
| 5941 | 5904 |
| 5942 | 5905 |
| 5943 #undef __ | 5906 #undef __ |
| 5944 | 5907 |
| 5945 } } // namespace v8::internal | 5908 } } // namespace v8::internal |
| OLD | NEW |