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 |