OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <limits.h> // For LONG_MIN, LONG_MAX. | 5 #include <limits.h> // For LONG_MIN, LONG_MAX. |
6 | 6 |
7 #if V8_TARGET_ARCH_MIPS64 | 7 #if V8_TARGET_ARCH_MIPS64 |
8 | 8 |
9 #include "src/base/division-by-constant.h" | 9 #include "src/base/division-by-constant.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 3516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3527 Branch(gc_required, Ugreater, scratch2, Operand(t9)); | 3527 Branch(gc_required, Ugreater, scratch2, Operand(t9)); |
3528 sd(scratch2, MemOperand(topaddr)); | 3528 sd(scratch2, MemOperand(topaddr)); |
3529 | 3529 |
3530 // Tag object if requested. | 3530 // Tag object if requested. |
3531 if ((flags & TAG_OBJECT) != 0) { | 3531 if ((flags & TAG_OBJECT) != 0) { |
3532 Daddu(result, result, Operand(kHeapObjectTag)); | 3532 Daddu(result, result, Operand(kHeapObjectTag)); |
3533 } | 3533 } |
3534 } | 3534 } |
3535 | 3535 |
3536 | 3536 |
3537 void MacroAssembler::Allocate(Register object_size, | 3537 void MacroAssembler::Allocate(Register object_size, Register result, |
3538 Register result, | 3538 Register result_end, Register scratch, |
3539 Register scratch1, | 3539 Label* gc_required, AllocationFlags flags) { |
3540 Register scratch2, | |
3541 Label* gc_required, | |
3542 AllocationFlags flags) { | |
3543 if (!FLAG_inline_new) { | 3540 if (!FLAG_inline_new) { |
3544 if (emit_debug_code()) { | 3541 if (emit_debug_code()) { |
3545 // Trash the registers to simulate an allocation failure. | 3542 // Trash the registers to simulate an allocation failure. |
3546 li(result, 0x7091); | 3543 li(result, 0x7091); |
3547 li(scratch1, 0x7191); | 3544 li(scratch, 0x7191); |
3548 li(scratch2, 0x7291); | 3545 li(result_end, 0x7291); |
3549 } | 3546 } |
3550 jmp(gc_required); | 3547 jmp(gc_required); |
3551 return; | 3548 return; |
3552 } | 3549 } |
3553 | 3550 |
3554 DCHECK(!result.is(scratch1)); | 3551 DCHECK(!result.is(scratch)); |
3555 DCHECK(!result.is(scratch2)); | 3552 DCHECK(!result.is(result_end)); |
3556 DCHECK(!scratch1.is(scratch2)); | 3553 DCHECK(!scratch.is(result_end)); |
3557 DCHECK(!object_size.is(t9)); | 3554 DCHECK(!object_size.is(t9)); |
3558 DCHECK(!scratch1.is(t9) && !scratch2.is(t9) && !result.is(t9)); | 3555 DCHECK(!scratch.is(t9) && !result_end.is(t9) && !result.is(t9)); |
3559 | 3556 |
3560 // Check relative positions of allocation top and limit addresses. | 3557 // Check relative positions of allocation top and limit addresses. |
3561 // ARM adds additional checks to make sure the ldm instruction can be | 3558 // ARM adds additional checks to make sure the ldm instruction can be |
3562 // used. On MIPS we don't have ldm so we don't need additional checks either. | 3559 // used. On MIPS we don't have ldm so we don't need additional checks either. |
3563 ExternalReference allocation_top = | 3560 ExternalReference allocation_top = |
3564 AllocationUtils::GetAllocationTopReference(isolate(), flags); | 3561 AllocationUtils::GetAllocationTopReference(isolate(), flags); |
3565 ExternalReference allocation_limit = | 3562 ExternalReference allocation_limit = |
3566 AllocationUtils::GetAllocationLimitReference(isolate(), flags); | 3563 AllocationUtils::GetAllocationLimitReference(isolate(), flags); |
3567 intptr_t top = | 3564 intptr_t top = |
3568 reinterpret_cast<intptr_t>(allocation_top.address()); | 3565 reinterpret_cast<intptr_t>(allocation_top.address()); |
3569 intptr_t limit = | 3566 intptr_t limit = |
3570 reinterpret_cast<intptr_t>(allocation_limit.address()); | 3567 reinterpret_cast<intptr_t>(allocation_limit.address()); |
3571 DCHECK((limit - top) == kPointerSize); | 3568 DCHECK((limit - top) == kPointerSize); |
3572 | 3569 |
3573 // Set up allocation top address and object size registers. | 3570 // Set up allocation top address and object size registers. |
3574 Register topaddr = scratch1; | 3571 Register topaddr = scratch; |
3575 li(topaddr, Operand(allocation_top)); | 3572 li(topaddr, Operand(allocation_top)); |
3576 | 3573 |
3577 // This code stores a temporary value in t9. | 3574 // This code stores a temporary value in t9. |
3578 if ((flags & RESULT_CONTAINS_TOP) == 0) { | 3575 if ((flags & RESULT_CONTAINS_TOP) == 0) { |
3579 // Load allocation top into result and allocation limit into t9. | 3576 // Load allocation top into result and allocation limit into t9. |
3580 ld(result, MemOperand(topaddr)); | 3577 ld(result, MemOperand(topaddr)); |
3581 ld(t9, MemOperand(topaddr, kPointerSize)); | 3578 ld(t9, MemOperand(topaddr, kPointerSize)); |
3582 } else { | 3579 } else { |
3583 if (emit_debug_code()) { | 3580 if (emit_debug_code()) { |
3584 // Assert that result actually contains top on entry. t9 is used | 3581 // Assert that result actually contains top on entry. t9 is used |
3585 // immediately below so this use of t9 does not cause difference with | 3582 // immediately below so this use of t9 does not cause difference with |
3586 // respect to register content between debug and release mode. | 3583 // respect to register content between debug and release mode. |
3587 ld(t9, MemOperand(topaddr)); | 3584 ld(t9, MemOperand(topaddr)); |
3588 Check(eq, kUnexpectedAllocationTop, result, Operand(t9)); | 3585 Check(eq, kUnexpectedAllocationTop, result, Operand(t9)); |
3589 } | 3586 } |
3590 // Load allocation limit into t9. Result already contains allocation top. | 3587 // Load allocation limit into t9. Result already contains allocation top. |
3591 ld(t9, MemOperand(topaddr, static_cast<int32_t>(limit - top))); | 3588 ld(t9, MemOperand(topaddr, static_cast<int32_t>(limit - top))); |
3592 } | 3589 } |
3593 | 3590 |
3594 DCHECK(kPointerSize == kDoubleSize); | 3591 DCHECK(kPointerSize == kDoubleSize); |
3595 if (emit_debug_code()) { | 3592 if (emit_debug_code()) { |
3596 And(at, result, Operand(kDoubleAlignmentMask)); | 3593 And(at, result, Operand(kDoubleAlignmentMask)); |
3597 Check(eq, kAllocationIsNotDoubleAligned, at, Operand(zero_reg)); | 3594 Check(eq, kAllocationIsNotDoubleAligned, at, Operand(zero_reg)); |
3598 } | 3595 } |
3599 | 3596 |
3600 // Calculate new top and bail out if new space is exhausted. Use result | 3597 // Calculate new top and bail out if new space is exhausted. Use result |
3601 // to calculate the new top. Object size may be in words so a shift is | 3598 // to calculate the new top. Object size may be in words so a shift is |
3602 // required to get the number of bytes. | 3599 // required to get the number of bytes. |
3603 if ((flags & SIZE_IN_WORDS) != 0) { | 3600 if ((flags & SIZE_IN_WORDS) != 0) { |
3604 dsll(scratch2, object_size, kPointerSizeLog2); | 3601 dsll(result_end, object_size, kPointerSizeLog2); |
3605 Daddu(scratch2, result, scratch2); | 3602 Daddu(result_end, result, result_end); |
3606 } else { | 3603 } else { |
3607 Daddu(scratch2, result, Operand(object_size)); | 3604 Daddu(result_end, result, Operand(object_size)); |
3608 } | 3605 } |
3609 Branch(gc_required, Ugreater, scratch2, Operand(t9)); | 3606 Branch(gc_required, Ugreater, result_end, Operand(t9)); |
3610 | 3607 |
3611 // Update allocation top. result temporarily holds the new top. | 3608 // Update allocation top. result temporarily holds the new top. |
3612 if (emit_debug_code()) { | 3609 if (emit_debug_code()) { |
3613 And(t9, scratch2, Operand(kObjectAlignmentMask)); | 3610 And(t9, result_end, Operand(kObjectAlignmentMask)); |
3614 Check(eq, kUnalignedAllocationInNewSpace, t9, Operand(zero_reg)); | 3611 Check(eq, kUnalignedAllocationInNewSpace, t9, Operand(zero_reg)); |
3615 } | 3612 } |
3616 sd(scratch2, MemOperand(topaddr)); | 3613 sd(result_end, MemOperand(topaddr)); |
3617 | 3614 |
3618 // Tag object if requested. | 3615 // Tag object if requested. |
3619 if ((flags & TAG_OBJECT) != 0) { | 3616 if ((flags & TAG_OBJECT) != 0) { |
3620 Daddu(result, result, Operand(kHeapObjectTag)); | 3617 Daddu(result, result, Operand(kHeapObjectTag)); |
3621 } | 3618 } |
3622 } | 3619 } |
3623 | 3620 |
3624 | 3621 |
3625 void MacroAssembler::AllocateTwoByteString(Register result, | 3622 void MacroAssembler::AllocateTwoByteString(Register result, |
3626 Register length, | 3623 Register length, |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3892 lbu(scratch, MemOperand(src)); | 3889 lbu(scratch, MemOperand(src)); |
3893 Daddu(src, src, 1); | 3890 Daddu(src, src, 1); |
3894 sb(scratch, MemOperand(dst)); | 3891 sb(scratch, MemOperand(dst)); |
3895 Daddu(dst, dst, 1); | 3892 Daddu(dst, dst, 1); |
3896 Dsubu(length, length, Operand(1)); | 3893 Dsubu(length, length, Operand(1)); |
3897 Branch(&byte_loop_1, ne, length, Operand(zero_reg)); | 3894 Branch(&byte_loop_1, ne, length, Operand(zero_reg)); |
3898 bind(&done); | 3895 bind(&done); |
3899 } | 3896 } |
3900 | 3897 |
3901 | 3898 |
3902 void MacroAssembler::InitializeFieldsWithFiller(Register start_offset, | 3899 void MacroAssembler::InitializeFieldsWithFiller(Register current_address, |
3903 Register end_offset, | 3900 Register end_address, |
3904 Register filler) { | 3901 Register filler) { |
3905 Label loop, entry; | 3902 Label loop, entry; |
3906 Branch(&entry); | 3903 Branch(&entry); |
3907 bind(&loop); | 3904 bind(&loop); |
3908 sd(filler, MemOperand(start_offset)); | 3905 sd(filler, MemOperand(current_address)); |
3909 Daddu(start_offset, start_offset, kPointerSize); | 3906 Daddu(current_address, current_address, kPointerSize); |
3910 bind(&entry); | 3907 bind(&entry); |
3911 Branch(&loop, ult, start_offset, Operand(end_offset)); | 3908 Branch(&loop, ult, current_address, Operand(end_address)); |
3912 } | 3909 } |
3913 | 3910 |
3914 | 3911 |
3915 void MacroAssembler::CheckFastElements(Register map, | 3912 void MacroAssembler::CheckFastElements(Register map, |
3916 Register scratch, | 3913 Register scratch, |
3917 Label* fail) { | 3914 Label* fail) { |
3918 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); | 3915 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); |
3919 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | 3916 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); |
3920 STATIC_ASSERT(FAST_ELEMENTS == 2); | 3917 STATIC_ASSERT(FAST_ELEMENTS == 2); |
3921 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); | 3918 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); |
(...skipping 2315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6237 if (mag.shift > 0) sra(result, result, mag.shift); | 6234 if (mag.shift > 0) sra(result, result, mag.shift); |
6238 srl(at, dividend, 31); | 6235 srl(at, dividend, 31); |
6239 Addu(result, result, Operand(at)); | 6236 Addu(result, result, Operand(at)); |
6240 } | 6237 } |
6241 | 6238 |
6242 | 6239 |
6243 } // namespace internal | 6240 } // namespace internal |
6244 } // namespace v8 | 6241 } // namespace v8 |
6245 | 6242 |
6246 #endif // V8_TARGET_ARCH_MIPS64 | 6243 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |