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 3618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3629 __ VFPCompareAndSetFlags(double_scratch, double_exponent); | 3629 __ VFPCompareAndSetFlags(double_scratch, double_exponent); |
3630 __ b(eq, &int_exponent_convert); | 3630 __ b(eq, &int_exponent_convert); |
3631 | 3631 |
3632 if (exponent_type_ == ON_STACK) { | 3632 if (exponent_type_ == ON_STACK) { |
3633 // Detect square root case. Crankshaft detects constant +/-0.5 at | 3633 // Detect square root case. Crankshaft detects constant +/-0.5 at |
3634 // compile time and uses DoMathPowHalf instead. We then skip this check | 3634 // compile time and uses DoMathPowHalf instead. We then skip this check |
3635 // for non-constant cases of +/-0.5 as these hardly occur. | 3635 // for non-constant cases of +/-0.5 as these hardly occur. |
3636 Label not_plus_half; | 3636 Label not_plus_half; |
3637 | 3637 |
3638 // Test for 0.5. | 3638 // Test for 0.5. |
3639 __ vmov(double_scratch, 0.5, scratch); | 3639 __ vmov(double_scratch, 0.5); |
3640 __ VFPCompareAndSetFlags(double_exponent, double_scratch); | 3640 __ VFPCompareAndSetFlags(double_exponent, double_scratch); |
3641 __ b(ne, ¬_plus_half); | 3641 __ b(ne, ¬_plus_half); |
3642 | 3642 |
3643 // Calculates square root of base. Check for the special case of | 3643 // Calculates square root of base. Check for the special case of |
3644 // Math.pow(-Infinity, 0.5) == Infinity (ECMA spec, 15.8.2.13). | 3644 // Math.pow(-Infinity, 0.5) == Infinity (ECMA spec, 15.8.2.13). |
3645 __ vmov(double_scratch, -V8_INFINITY, scratch); | 3645 __ vmov(double_scratch, -V8_INFINITY); |
3646 __ VFPCompareAndSetFlags(double_base, double_scratch); | 3646 __ VFPCompareAndSetFlags(double_base, double_scratch); |
3647 __ vneg(double_result, double_scratch, eq); | 3647 __ vneg(double_result, double_scratch, eq); |
3648 __ b(eq, &done); | 3648 __ b(eq, &done); |
3649 | 3649 |
3650 // Add +0 to convert -0 to +0. | 3650 // Add +0 to convert -0 to +0. |
3651 __ vadd(double_scratch, double_base, kDoubleRegZero); | 3651 __ vadd(double_scratch, double_base, kDoubleRegZero); |
3652 __ vsqrt(double_result, double_scratch); | 3652 __ vsqrt(double_result, double_scratch); |
3653 __ jmp(&done); | 3653 __ jmp(&done); |
3654 | 3654 |
3655 __ bind(¬_plus_half); | 3655 __ bind(¬_plus_half); |
3656 __ vmov(double_scratch, -0.5, scratch); | 3656 __ vmov(double_scratch, -0.5); |
3657 __ VFPCompareAndSetFlags(double_exponent, double_scratch); | 3657 __ VFPCompareAndSetFlags(double_exponent, double_scratch); |
3658 __ b(ne, &call_runtime); | 3658 __ b(ne, &call_runtime); |
3659 | 3659 |
3660 // Calculates square root of base. Check for the special case of | 3660 // Calculates square root of base. Check for the special case of |
3661 // Math.pow(-Infinity, -0.5) == 0 (ECMA spec, 15.8.2.13). | 3661 // Math.pow(-Infinity, -0.5) == 0 (ECMA spec, 15.8.2.13). |
3662 __ vmov(double_scratch, -V8_INFINITY, scratch); | 3662 __ vmov(double_scratch, -V8_INFINITY); |
3663 __ VFPCompareAndSetFlags(double_base, double_scratch); | 3663 __ VFPCompareAndSetFlags(double_base, double_scratch); |
3664 __ vmov(double_result, kDoubleRegZero, eq); | 3664 __ vmov(double_result, kDoubleRegZero, eq); |
3665 __ b(eq, &done); | 3665 __ b(eq, &done); |
3666 | 3666 |
3667 // Add +0 to convert -0 to +0. | 3667 // Add +0 to convert -0 to +0. |
3668 __ vadd(double_scratch, double_base, kDoubleRegZero); | 3668 __ vadd(double_scratch, double_base, kDoubleRegZero); |
3669 __ vmov(double_result, 1.0, scratch); | 3669 __ vmov(double_result, 1.0); |
3670 __ vsqrt(double_scratch, double_scratch); | 3670 __ vsqrt(double_scratch, double_scratch); |
3671 __ vdiv(double_result, double_result, double_scratch); | 3671 __ vdiv(double_result, double_result, double_scratch); |
3672 __ jmp(&done); | 3672 __ jmp(&done); |
3673 } | 3673 } |
3674 | 3674 |
3675 __ push(lr); | 3675 __ push(lr); |
3676 { | 3676 { |
3677 AllowExternalCallThatCantCauseGC scope(masm); | 3677 AllowExternalCallThatCantCauseGC scope(masm); |
3678 __ PrepareCallCFunction(0, 2, scratch); | 3678 __ PrepareCallCFunction(0, 2, scratch); |
3679 __ SetCallCDoubleArguments(double_base, double_exponent); | 3679 __ SetCallCDoubleArguments(double_base, double_exponent); |
(...skipping 14 matching lines...) Expand all Loading... |
3694 __ bind(&int_exponent); | 3694 __ bind(&int_exponent); |
3695 | 3695 |
3696 // Get two copies of exponent in the registers scratch and exponent. | 3696 // Get two copies of exponent in the registers scratch and exponent. |
3697 if (exponent_type_ == INTEGER) { | 3697 if (exponent_type_ == INTEGER) { |
3698 __ mov(scratch, exponent); | 3698 __ mov(scratch, exponent); |
3699 } else { | 3699 } else { |
3700 // Exponent has previously been stored into scratch as untagged integer. | 3700 // Exponent has previously been stored into scratch as untagged integer. |
3701 __ mov(exponent, scratch); | 3701 __ mov(exponent, scratch); |
3702 } | 3702 } |
3703 __ vmov(double_scratch, double_base); // Back up base. | 3703 __ vmov(double_scratch, double_base); // Back up base. |
3704 __ vmov(double_result, 1.0, scratch2); | 3704 __ vmov(double_result, 1.0); |
3705 | 3705 |
3706 // Get absolute value of exponent. | 3706 // Get absolute value of exponent. |
3707 __ cmp(scratch, Operand(0)); | 3707 __ cmp(scratch, Operand(0)); |
3708 __ mov(scratch2, Operand(0), LeaveCC, mi); | 3708 __ mov(scratch2, Operand(0), LeaveCC, mi); |
3709 __ sub(scratch, scratch2, scratch, LeaveCC, mi); | 3709 __ sub(scratch, scratch2, scratch, LeaveCC, mi); |
3710 | 3710 |
3711 Label while_true; | 3711 Label while_true; |
3712 __ bind(&while_true); | 3712 __ bind(&while_true); |
3713 __ mov(scratch, Operand(scratch, ASR, 1), SetCC); | 3713 __ mov(scratch, Operand(scratch, ASR, 1), SetCC); |
3714 __ vmul(double_result, double_result, double_scratch, cs); | 3714 __ vmul(double_result, double_result, double_scratch, cs); |
3715 __ vmul(double_scratch, double_scratch, double_scratch, ne); | 3715 __ vmul(double_scratch, double_scratch, double_scratch, ne); |
3716 __ b(ne, &while_true); | 3716 __ b(ne, &while_true); |
3717 | 3717 |
3718 __ cmp(exponent, Operand(0)); | 3718 __ cmp(exponent, Operand(0)); |
3719 __ b(ge, &done); | 3719 __ b(ge, &done); |
3720 __ vmov(double_scratch, 1.0, scratch); | 3720 __ vmov(double_scratch, 1.0); |
3721 __ vdiv(double_result, double_scratch, double_result); | 3721 __ vdiv(double_result, double_scratch, double_result); |
3722 // Test whether result is zero. Bail out to check for subnormal result. | 3722 // Test whether result is zero. Bail out to check for subnormal result. |
3723 // Due to subnormals, x^-y == (1/x)^y does not hold in all cases. | 3723 // Due to subnormals, x^-y == (1/x)^y does not hold in all cases. |
3724 __ VFPCompareAndSetFlags(double_result, 0.0); | 3724 __ VFPCompareAndSetFlags(double_result, 0.0); |
3725 __ b(ne, &done); | 3725 __ b(ne, &done); |
3726 // double_exponent may not containe the exponent value if the input was a | 3726 // double_exponent may not containe the exponent value if the input was a |
3727 // smi. We set it with exponent value before bailing out. | 3727 // smi. We set it with exponent value before bailing out. |
3728 __ vmov(single_scratch, exponent); | 3728 __ vmov(single_scratch, exponent); |
3729 __ vcvt_f64_s32(double_exponent, single_scratch); | 3729 __ vcvt_f64_s32(double_exponent, single_scratch); |
3730 | 3730 |
(...skipping 3524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7255 // StoreArrayLiteralElementStub::Generate | 7255 // StoreArrayLiteralElementStub::Generate |
7256 { REG(r5), REG(r0), REG(r6), EMIT_REMEMBERED_SET }, | 7256 { REG(r5), REG(r0), REG(r6), EMIT_REMEMBERED_SET }, |
7257 // FastNewClosureStub::Generate | 7257 // FastNewClosureStub::Generate |
7258 { REG(r2), REG(r4), REG(r1), EMIT_REMEMBERED_SET }, | 7258 { REG(r2), REG(r4), REG(r1), EMIT_REMEMBERED_SET }, |
7259 // Null termination. | 7259 // Null termination. |
7260 { REG(no_reg), REG(no_reg), REG(no_reg), EMIT_REMEMBERED_SET} | 7260 { REG(no_reg), REG(no_reg), REG(no_reg), EMIT_REMEMBERED_SET} |
7261 }; | 7261 }; |
7262 | 7262 |
7263 #undef REG | 7263 #undef REG |
7264 | 7264 |
7265 | |
7266 bool RecordWriteStub::IsPregenerated() { | 7265 bool RecordWriteStub::IsPregenerated() { |
7267 for (const AheadOfTimeWriteBarrierStubList* entry = kAheadOfTime; | 7266 for (const AheadOfTimeWriteBarrierStubList* entry = kAheadOfTime; |
7268 !entry->object.is(no_reg); | 7267 !entry->object.is(no_reg); |
7269 entry++) { | 7268 entry++) { |
7270 if (object_.is(entry->object) && | 7269 if (object_.is(entry->object) && |
7271 value_.is(entry->value) && | 7270 value_.is(entry->value) && |
7272 address_.is(entry->address) && | 7271 address_.is(entry->address) && |
7273 remembered_set_action_ == entry->action && | 7272 remembered_set_action_ == entry->action && |
7274 save_fp_regs_mode_ == kDontSaveFPRegs) { | 7273 save_fp_regs_mode_ == kDontSaveFPRegs) { |
7275 return true; | 7274 return true; |
(...skipping 21 matching lines...) Expand all Loading... |
7297 RecordWriteStub stub(entry->object, | 7296 RecordWriteStub stub(entry->object, |
7298 entry->value, | 7297 entry->value, |
7299 entry->address, | 7298 entry->address, |
7300 entry->action, | 7299 entry->action, |
7301 kDontSaveFPRegs); | 7300 kDontSaveFPRegs); |
7302 stub.GetCode()->set_is_pregenerated(true); | 7301 stub.GetCode()->set_is_pregenerated(true); |
7303 } | 7302 } |
7304 } | 7303 } |
7305 | 7304 |
7306 | 7305 |
7307 bool CodeStub::CanUseFPRegisters() { | |
7308 return CpuFeatures::IsSupported(VFP2); | |
7309 } | |
7310 | |
7311 | |
7312 // Takes the input in 3 registers: address_ value_ and object_. A pointer to | 7306 // Takes the input in 3 registers: address_ value_ and object_. A pointer to |
7313 // the value has just been written into the object, now this stub makes sure | 7307 // the value has just been written into the object, now this stub makes sure |
7314 // we keep the GC informed. The word in the object where the value has been | 7308 // we keep the GC informed. The word in the object where the value has been |
7315 // written is in the address register. | 7309 // written is in the address register. |
7316 void RecordWriteStub::Generate(MacroAssembler* masm) { | 7310 void RecordWriteStub::Generate(MacroAssembler* masm) { |
7317 Label skip_to_incremental_noncompacting; | 7311 Label skip_to_incremental_noncompacting; |
7318 Label skip_to_incremental_compacting; | 7312 Label skip_to_incremental_compacting; |
7319 | 7313 |
7320 // The first two instructions are generated with labels so as to get the | 7314 // The first two instructions are generated with labels so as to get the |
7321 // offset fixed up correctly by the bind(Label*) call. We patch it back and | 7315 // offset fixed up correctly by the bind(Label*) call. We patch it back and |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7430 | 7424 |
7431 | 7425 |
7432 void RecordWriteStub::CheckNeedsToInformIncrementalMarker( | 7426 void RecordWriteStub::CheckNeedsToInformIncrementalMarker( |
7433 MacroAssembler* masm, | 7427 MacroAssembler* masm, |
7434 OnNoNeedToInformIncrementalMarker on_no_need, | 7428 OnNoNeedToInformIncrementalMarker on_no_need, |
7435 Mode mode) { | 7429 Mode mode) { |
7436 Label on_black; | 7430 Label on_black; |
7437 Label need_incremental; | 7431 Label need_incremental; |
7438 Label need_incremental_pop_scratch; | 7432 Label need_incremental_pop_scratch; |
7439 | 7433 |
7440 __ and_(regs_.scratch0(), regs_.object(), Operand(~Page::kPageAlignmentMask)); | |
7441 __ ldr(regs_.scratch1(), | |
7442 MemOperand(regs_.scratch0(), | |
7443 MemoryChunk::kWriteBarrierCounterOffset)); | |
7444 __ sub(regs_.scratch1(), regs_.scratch1(), Operand(1), SetCC); | |
7445 __ str(regs_.scratch1(), | |
7446 MemOperand(regs_.scratch0(), | |
7447 MemoryChunk::kWriteBarrierCounterOffset)); | |
7448 __ b(mi, &need_incremental); | |
7449 | |
7450 // Let's look at the color of the object: If it is not black we don't have | 7434 // Let's look at the color of the object: If it is not black we don't have |
7451 // to inform the incremental marker. | 7435 // to inform the incremental marker. |
7452 __ JumpIfBlack(regs_.object(), regs_.scratch0(), regs_.scratch1(), &on_black); | 7436 __ JumpIfBlack(regs_.object(), regs_.scratch0(), regs_.scratch1(), &on_black); |
7453 | 7437 |
7454 regs_.Restore(masm); | 7438 regs_.Restore(masm); |
7455 if (on_no_need == kUpdateRememberedSetOnNoNeedToInformIncrementalMarker) { | 7439 if (on_no_need == kUpdateRememberedSetOnNoNeedToInformIncrementalMarker) { |
7456 __ RememberedSetHelper(object_, | 7440 __ RememberedSetHelper(object_, |
7457 address_, | 7441 address_, |
7458 value_, | 7442 value_, |
7459 save_fp_regs_mode_, | 7443 save_fp_regs_mode_, |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7560 // and value is Smi. | 7544 // and value is Smi. |
7561 __ bind(&smi_element); | 7545 __ bind(&smi_element); |
7562 __ ldr(r5, FieldMemOperand(r1, JSObject::kElementsOffset)); | 7546 __ ldr(r5, FieldMemOperand(r1, JSObject::kElementsOffset)); |
7563 __ add(r6, r5, Operand(r3, LSL, kPointerSizeLog2 - kSmiTagSize)); | 7547 __ add(r6, r5, Operand(r3, LSL, kPointerSizeLog2 - kSmiTagSize)); |
7564 __ str(r0, FieldMemOperand(r6, FixedArray::kHeaderSize)); | 7548 __ str(r0, FieldMemOperand(r6, FixedArray::kHeaderSize)); |
7565 __ Ret(); | 7549 __ Ret(); |
7566 | 7550 |
7567 // Array literal has ElementsKind of FAST_DOUBLE_ELEMENTS. | 7551 // Array literal has ElementsKind of FAST_DOUBLE_ELEMENTS. |
7568 __ bind(&double_elements); | 7552 __ bind(&double_elements); |
7569 __ ldr(r5, FieldMemOperand(r1, JSObject::kElementsOffset)); | 7553 __ ldr(r5, FieldMemOperand(r1, JSObject::kElementsOffset)); |
7570 __ StoreNumberToDoubleElements(r0, r3, r1, | 7554 __ StoreNumberToDoubleElements(r0, r3, r1, r5, r6, r7, r9, r2, |
7571 // Overwrites all regs after this. | |
7572 r5, r6, r7, r9, r2, | |
7573 &slow_elements); | 7555 &slow_elements); |
7574 __ Ret(); | 7556 __ Ret(); |
7575 } | 7557 } |
7576 | 7558 |
7577 | 7559 |
7578 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { | 7560 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { |
7579 if (entry_hook_ != NULL) { | 7561 if (entry_hook_ != NULL) { |
7580 ProfileEntryHookStub stub; | 7562 ProfileEntryHookStub stub; |
7581 __ push(lr); | 7563 __ push(lr); |
7582 __ CallStub(&stub); | 7564 __ CallStub(&stub); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7631 | 7613 |
7632 __ Pop(lr, r5, r1); | 7614 __ Pop(lr, r5, r1); |
7633 __ Ret(); | 7615 __ Ret(); |
7634 } | 7616 } |
7635 | 7617 |
7636 #undef __ | 7618 #undef __ |
7637 | 7619 |
7638 } } // namespace v8::internal | 7620 } } // namespace v8::internal |
7639 | 7621 |
7640 #endif // V8_TARGET_ARCH_ARM | 7622 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |