| OLD | NEW |
| 1 | 1 |
| 2 // Copyright 2012 the V8 project authors. All rights reserved. | 2 // Copyright 2012 the V8 project authors. All rights reserved. |
| 3 // Use of this source code is governed by a BSD-style license that can be | 3 // Use of this source code is governed by a BSD-style license that can be |
| 4 // found in the LICENSE file. | 4 // found in the LICENSE file. |
| 5 | 5 |
| 6 #include <limits.h> // For LONG_MIN, LONG_MAX. | 6 #include <limits.h> // For LONG_MIN, LONG_MAX. |
| 7 | 7 |
| 8 #if V8_TARGET_ARCH_MIPS | 8 #if V8_TARGET_ARCH_MIPS |
| 9 | 9 |
| 10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
| (...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 SmiUntag(scratch); | 492 SmiUntag(scratch); |
| 493 | 493 |
| 494 // Xor original key with a seed. | 494 // Xor original key with a seed. |
| 495 xor_(reg0, reg0, scratch); | 495 xor_(reg0, reg0, scratch); |
| 496 | 496 |
| 497 // Compute the hash code from the untagged key. This must be kept in sync | 497 // Compute the hash code from the untagged key. This must be kept in sync |
| 498 // with ComputeIntegerHash in utils.h. | 498 // with ComputeIntegerHash in utils.h. |
| 499 // | 499 // |
| 500 // hash = ~hash + (hash << 15); | 500 // hash = ~hash + (hash << 15); |
| 501 nor(scratch, reg0, zero_reg); | 501 nor(scratch, reg0, zero_reg); |
| 502 sll(at, reg0, 15); | 502 Lsa(reg0, scratch, reg0, 15); |
| 503 addu(reg0, scratch, at); | |
| 504 | 503 |
| 505 // hash = hash ^ (hash >> 12); | 504 // hash = hash ^ (hash >> 12); |
| 506 srl(at, reg0, 12); | 505 srl(at, reg0, 12); |
| 507 xor_(reg0, reg0, at); | 506 xor_(reg0, reg0, at); |
| 508 | 507 |
| 509 // hash = hash + (hash << 2); | 508 // hash = hash + (hash << 2); |
| 510 sll(at, reg0, 2); | 509 Lsa(reg0, reg0, reg0, 2); |
| 511 addu(reg0, reg0, at); | |
| 512 | 510 |
| 513 // hash = hash ^ (hash >> 4); | 511 // hash = hash ^ (hash >> 4); |
| 514 srl(at, reg0, 4); | 512 srl(at, reg0, 4); |
| 515 xor_(reg0, reg0, at); | 513 xor_(reg0, reg0, at); |
| 516 | 514 |
| 517 // hash = hash * 2057; | 515 // hash = hash * 2057; |
| 518 sll(scratch, reg0, 11); | 516 sll(scratch, reg0, 11); |
| 519 sll(at, reg0, 3); | 517 Lsa(reg0, reg0, reg0, 3); |
| 520 addu(reg0, reg0, at); | |
| 521 addu(reg0, reg0, scratch); | 518 addu(reg0, reg0, scratch); |
| 522 | 519 |
| 523 // hash = hash ^ (hash >> 16); | 520 // hash = hash ^ (hash >> 16); |
| 524 srl(at, reg0, 16); | 521 srl(at, reg0, 16); |
| 525 xor_(reg0, reg0, at); | 522 xor_(reg0, reg0, at); |
| 526 And(reg0, reg0, Operand(0x3fffffff)); | 523 And(reg0, reg0, Operand(0x3fffffff)); |
| 527 } | 524 } |
| 528 | 525 |
| 529 | 526 |
| 530 void MacroAssembler::LoadFromNumberDictionary(Label* miss, | 527 void MacroAssembler::LoadFromNumberDictionary(Label* miss, |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 570 // Use reg2 for index calculations and keep the hash intact in reg0. | 567 // Use reg2 for index calculations and keep the hash intact in reg0. |
| 571 mov(reg2, reg0); | 568 mov(reg2, reg0); |
| 572 // Compute the masked index: (hash + i + i * i) & mask. | 569 // Compute the masked index: (hash + i + i * i) & mask. |
| 573 if (i > 0) { | 570 if (i > 0) { |
| 574 Addu(reg2, reg2, Operand(SeededNumberDictionary::GetProbeOffset(i))); | 571 Addu(reg2, reg2, Operand(SeededNumberDictionary::GetProbeOffset(i))); |
| 575 } | 572 } |
| 576 and_(reg2, reg2, reg1); | 573 and_(reg2, reg2, reg1); |
| 577 | 574 |
| 578 // Scale the index by multiplying by the element size. | 575 // Scale the index by multiplying by the element size. |
| 579 DCHECK(SeededNumberDictionary::kEntrySize == 3); | 576 DCHECK(SeededNumberDictionary::kEntrySize == 3); |
| 580 sll(at, reg2, 1); // 2x. | 577 Lsa(reg2, reg2, reg2, 1); // reg2 = reg2 * 3. |
| 581 addu(reg2, reg2, at); // reg2 = reg2 * 3. | |
| 582 | 578 |
| 583 // Check if the key is identical to the name. | 579 // Check if the key is identical to the name. |
| 584 sll(at, reg2, kPointerSizeLog2); | 580 Lsa(reg2, elements, reg2, kPointerSizeLog2); |
| 585 addu(reg2, elements, at); | |
| 586 | 581 |
| 587 lw(at, FieldMemOperand(reg2, SeededNumberDictionary::kElementsStartOffset)); | 582 lw(at, FieldMemOperand(reg2, SeededNumberDictionary::kElementsStartOffset)); |
| 588 if (i != kNumberDictionaryProbes - 1) { | 583 if (i != kNumberDictionaryProbes - 1) { |
| 589 Branch(&done, eq, key, Operand(at)); | 584 Branch(&done, eq, key, Operand(at)); |
| 590 } else { | 585 } else { |
| 591 Branch(miss, ne, key, Operand(at)); | 586 Branch(miss, ne, key, Operand(at)); |
| 592 } | 587 } |
| 593 } | 588 } |
| 594 | 589 |
| 595 bind(&done); | 590 bind(&done); |
| (...skipping 2809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3405 li(result_end, Operand(isolate()->factory()->one_pointer_filler_map())); | 3400 li(result_end, Operand(isolate()->factory()->one_pointer_filler_map())); |
| 3406 sw(result_end, MemOperand(result)); | 3401 sw(result_end, MemOperand(result)); |
| 3407 Addu(result, result, Operand(kDoubleSize / 2)); | 3402 Addu(result, result, Operand(kDoubleSize / 2)); |
| 3408 bind(&aligned); | 3403 bind(&aligned); |
| 3409 } | 3404 } |
| 3410 | 3405 |
| 3411 // Calculate new top and bail out if new space is exhausted. Use result | 3406 // Calculate new top and bail out if new space is exhausted. Use result |
| 3412 // to calculate the new top. Object size may be in words so a shift is | 3407 // to calculate the new top. Object size may be in words so a shift is |
| 3413 // required to get the number of bytes. | 3408 // required to get the number of bytes. |
| 3414 if ((flags & SIZE_IN_WORDS) != 0) { | 3409 if ((flags & SIZE_IN_WORDS) != 0) { |
| 3415 sll(result_end, object_size, kPointerSizeLog2); | 3410 Lsa(result_end, result, object_size, kPointerSizeLog2); |
| 3416 Addu(result_end, result, result_end); | |
| 3417 } else { | 3411 } else { |
| 3418 Addu(result_end, result, Operand(object_size)); | 3412 Addu(result_end, result, Operand(object_size)); |
| 3419 } | 3413 } |
| 3420 Branch(gc_required, Ugreater, result_end, Operand(alloc_limit)); | 3414 Branch(gc_required, Ugreater, result_end, Operand(alloc_limit)); |
| 3421 | 3415 |
| 3422 // Update allocation top. result temporarily holds the new top. | 3416 // Update allocation top. result temporarily holds the new top. |
| 3423 if (emit_debug_code()) { | 3417 if (emit_debug_code()) { |
| 3424 And(alloc_limit, result_end, Operand(kObjectAlignmentMask)); | 3418 And(alloc_limit, result_end, Operand(kObjectAlignmentMask)); |
| 3425 Check(eq, kUnalignedAllocationInNewSpace, alloc_limit, Operand(zero_reg)); | 3419 Check(eq, kUnalignedAllocationInNewSpace, alloc_limit, Operand(zero_reg)); |
| 3426 } | 3420 } |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3768 | 3762 |
| 3769 // Check for nan: all NaN values have a value greater (signed) than 0x7ff00000 | 3763 // Check for nan: all NaN values have a value greater (signed) than 0x7ff00000 |
| 3770 // in the exponent. | 3764 // in the exponent. |
| 3771 li(scratch1, Operand(kHoleNanUpper32 & HeapNumber::kExponentMask)); | 3765 li(scratch1, Operand(kHoleNanUpper32 & HeapNumber::kExponentMask)); |
| 3772 lw(exponent_reg, FieldMemOperand(value_reg, HeapNumber::kExponentOffset)); | 3766 lw(exponent_reg, FieldMemOperand(value_reg, HeapNumber::kExponentOffset)); |
| 3773 Branch(&maybe_nan, ge, exponent_reg, Operand(scratch1)); | 3767 Branch(&maybe_nan, ge, exponent_reg, Operand(scratch1)); |
| 3774 | 3768 |
| 3775 lw(mantissa_reg, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset)); | 3769 lw(mantissa_reg, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset)); |
| 3776 | 3770 |
| 3777 bind(&have_double_value); | 3771 bind(&have_double_value); |
| 3778 sll(scratch1, key_reg, kDoubleSizeLog2 - kSmiTagSize); | 3772 Lsa(scratch1, elements_reg, key_reg, kDoubleSizeLog2 - kSmiTagSize); |
| 3779 Addu(scratch1, scratch1, elements_reg); | |
| 3780 sw(mantissa_reg, | 3773 sw(mantissa_reg, |
| 3781 FieldMemOperand(scratch1, FixedDoubleArray::kHeaderSize - elements_offset | 3774 FieldMemOperand(scratch1, FixedDoubleArray::kHeaderSize - elements_offset |
| 3782 + kHoleNanLower32Offset)); | 3775 + kHoleNanLower32Offset)); |
| 3783 sw(exponent_reg, | 3776 sw(exponent_reg, |
| 3784 FieldMemOperand(scratch1, FixedDoubleArray::kHeaderSize - elements_offset | 3777 FieldMemOperand(scratch1, FixedDoubleArray::kHeaderSize - elements_offset |
| 3785 + kHoleNanUpper32Offset)); | 3778 + kHoleNanUpper32Offset)); |
| 3786 jmp(&done); | 3779 jmp(&done); |
| 3787 | 3780 |
| 3788 bind(&maybe_nan); | 3781 bind(&maybe_nan); |
| 3789 // Could be NaN or Infinity. If fraction is not zero, it's NaN, otherwise | 3782 // Could be NaN or Infinity. If fraction is not zero, it's NaN, otherwise |
| 3790 // it's an Infinity, and the non-NaN code path applies. | 3783 // it's an Infinity, and the non-NaN code path applies. |
| 3791 Branch(&is_nan, gt, exponent_reg, Operand(scratch1)); | 3784 Branch(&is_nan, gt, exponent_reg, Operand(scratch1)); |
| 3792 lw(mantissa_reg, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset)); | 3785 lw(mantissa_reg, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset)); |
| 3793 Branch(&have_double_value, eq, mantissa_reg, Operand(zero_reg)); | 3786 Branch(&have_double_value, eq, mantissa_reg, Operand(zero_reg)); |
| 3794 bind(&is_nan); | 3787 bind(&is_nan); |
| 3795 // Load canonical NaN for storing into the double array. | 3788 // Load canonical NaN for storing into the double array. |
| 3796 LoadRoot(at, Heap::kNanValueRootIndex); | 3789 LoadRoot(at, Heap::kNanValueRootIndex); |
| 3797 lw(mantissa_reg, FieldMemOperand(at, HeapNumber::kMantissaOffset)); | 3790 lw(mantissa_reg, FieldMemOperand(at, HeapNumber::kMantissaOffset)); |
| 3798 lw(exponent_reg, FieldMemOperand(at, HeapNumber::kExponentOffset)); | 3791 lw(exponent_reg, FieldMemOperand(at, HeapNumber::kExponentOffset)); |
| 3799 jmp(&have_double_value); | 3792 jmp(&have_double_value); |
| 3800 | 3793 |
| 3801 bind(&smi_value); | 3794 bind(&smi_value); |
| 3802 Addu(scratch1, elements_reg, | 3795 Addu(scratch1, elements_reg, |
| 3803 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag - | 3796 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag - |
| 3804 elements_offset)); | 3797 elements_offset)); |
| 3805 sll(scratch2, key_reg, kDoubleSizeLog2 - kSmiTagSize); | 3798 Lsa(scratch1, scratch1, key_reg, kDoubleSizeLog2 - kSmiTagSize); |
| 3806 Addu(scratch1, scratch1, scratch2); | |
| 3807 // scratch1 is now effective address of the double element | 3799 // scratch1 is now effective address of the double element |
| 3808 | 3800 |
| 3809 Register untagged_value = scratch2; | 3801 Register untagged_value = scratch2; |
| 3810 SmiUntag(untagged_value, value_reg); | 3802 SmiUntag(untagged_value, value_reg); |
| 3811 mtc1(untagged_value, f2); | 3803 mtc1(untagged_value, f2); |
| 3812 cvt_d_w(f0, f2); | 3804 cvt_d_w(f0, f2); |
| 3813 sdc1(f0, MemOperand(scratch1, 0)); | 3805 sdc1(f0, MemOperand(scratch1, 0)); |
| 3814 bind(&done); | 3806 bind(&done); |
| 3815 } | 3807 } |
| 3816 | 3808 |
| (...skipping 1121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4938 | 4930 |
| 4939 // Pop the arguments, restore registers, and return. | 4931 // Pop the arguments, restore registers, and return. |
| 4940 mov(sp, fp); // Respect ABI stack constraint. | 4932 mov(sp, fp); // Respect ABI stack constraint. |
| 4941 lw(fp, MemOperand(sp, ExitFrameConstants::kCallerFPOffset)); | 4933 lw(fp, MemOperand(sp, ExitFrameConstants::kCallerFPOffset)); |
| 4942 lw(ra, MemOperand(sp, ExitFrameConstants::kCallerPCOffset)); | 4934 lw(ra, MemOperand(sp, ExitFrameConstants::kCallerPCOffset)); |
| 4943 | 4935 |
| 4944 if (argument_count.is_valid()) { | 4936 if (argument_count.is_valid()) { |
| 4945 if (argument_count_is_length) { | 4937 if (argument_count_is_length) { |
| 4946 addu(sp, sp, argument_count); | 4938 addu(sp, sp, argument_count); |
| 4947 } else { | 4939 } else { |
| 4948 sll(t8, argument_count, kPointerSizeLog2); | 4940 Lsa(sp, sp, argument_count, kPointerSizeLog2, t8); |
| 4949 addu(sp, sp, t8); | |
| 4950 } | 4941 } |
| 4951 } | 4942 } |
| 4952 | 4943 |
| 4953 if (do_return) { | 4944 if (do_return) { |
| 4954 Ret(USE_DELAY_SLOT); | 4945 Ret(USE_DELAY_SLOT); |
| 4955 // If returning, the instruction in the delay slot will be the addiu below. | 4946 // If returning, the instruction in the delay slot will be the addiu below. |
| 4956 } | 4947 } |
| 4957 addiu(sp, sp, 8); | 4948 addiu(sp, sp, 8); |
| 4958 } | 4949 } |
| 4959 | 4950 |
| (...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5466 | 5457 |
| 5467 | 5458 |
| 5468 void MacroAssembler::GetMarkBits(Register addr_reg, | 5459 void MacroAssembler::GetMarkBits(Register addr_reg, |
| 5469 Register bitmap_reg, | 5460 Register bitmap_reg, |
| 5470 Register mask_reg) { | 5461 Register mask_reg) { |
| 5471 DCHECK(!AreAliased(addr_reg, bitmap_reg, mask_reg, no_reg)); | 5462 DCHECK(!AreAliased(addr_reg, bitmap_reg, mask_reg, no_reg)); |
| 5472 And(bitmap_reg, addr_reg, Operand(~Page::kPageAlignmentMask)); | 5463 And(bitmap_reg, addr_reg, Operand(~Page::kPageAlignmentMask)); |
| 5473 Ext(mask_reg, addr_reg, kPointerSizeLog2, Bitmap::kBitsPerCellLog2); | 5464 Ext(mask_reg, addr_reg, kPointerSizeLog2, Bitmap::kBitsPerCellLog2); |
| 5474 const int kLowBits = kPointerSizeLog2 + Bitmap::kBitsPerCellLog2; | 5465 const int kLowBits = kPointerSizeLog2 + Bitmap::kBitsPerCellLog2; |
| 5475 Ext(t8, addr_reg, kLowBits, kPageSizeBits - kLowBits); | 5466 Ext(t8, addr_reg, kLowBits, kPageSizeBits - kLowBits); |
| 5476 sll(t8, t8, kPointerSizeLog2); | 5467 Lsa(bitmap_reg, bitmap_reg, t8, kPointerSizeLog2, t8); |
| 5477 Addu(bitmap_reg, bitmap_reg, t8); | |
| 5478 li(t8, Operand(1)); | 5468 li(t8, Operand(1)); |
| 5479 sllv(mask_reg, t8, mask_reg); | 5469 sllv(mask_reg, t8, mask_reg); |
| 5480 } | 5470 } |
| 5481 | 5471 |
| 5482 | 5472 |
| 5483 void MacroAssembler::JumpIfWhite(Register value, Register bitmap_scratch, | 5473 void MacroAssembler::JumpIfWhite(Register value, Register bitmap_scratch, |
| 5484 Register mask_scratch, Register load_scratch, | 5474 Register mask_scratch, Register load_scratch, |
| 5485 Label* value_is_white) { | 5475 Label* value_is_white) { |
| 5486 DCHECK(!AreAliased(value, bitmap_scratch, mask_scratch, t8)); | 5476 DCHECK(!AreAliased(value, bitmap_scratch, mask_scratch, t8)); |
| 5487 GetMarkBits(value, bitmap_scratch, mask_scratch); | 5477 GetMarkBits(value, bitmap_scratch, mask_scratch); |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5788 if (mag.shift > 0) sra(result, result, mag.shift); | 5778 if (mag.shift > 0) sra(result, result, mag.shift); |
| 5789 srl(at, dividend, 31); | 5779 srl(at, dividend, 31); |
| 5790 Addu(result, result, Operand(at)); | 5780 Addu(result, result, Operand(at)); |
| 5791 } | 5781 } |
| 5792 | 5782 |
| 5793 | 5783 |
| 5794 } // namespace internal | 5784 } // namespace internal |
| 5795 } // namespace v8 | 5785 } // namespace v8 |
| 5796 | 5786 |
| 5797 #endif // V8_TARGET_ARCH_MIPS | 5787 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |