| 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 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 496 | 496 |
| 497 // Xor original key with a seed. | 497 // Xor original key with a seed. |
| 498 xor_(reg0, reg0, scratch); | 498 xor_(reg0, reg0, scratch); |
| 499 | 499 |
| 500 // Compute the hash code from the untagged key. This must be kept in sync | 500 // Compute the hash code from the untagged key. This must be kept in sync |
| 501 // with ComputeIntegerHash in utils.h. | 501 // with ComputeIntegerHash in utils.h. |
| 502 // | 502 // |
| 503 // hash = ~hash + (hash << 15); | 503 // hash = ~hash + (hash << 15); |
| 504 // The algorithm uses 32-bit integer values. | 504 // The algorithm uses 32-bit integer values. |
| 505 nor(scratch, reg0, zero_reg); | 505 nor(scratch, reg0, zero_reg); |
| 506 sll(at, reg0, 15); | 506 Lsa(reg0, scratch, reg0, 15); |
| 507 addu(reg0, scratch, at); | |
| 508 | 507 |
| 509 // hash = hash ^ (hash >> 12); | 508 // hash = hash ^ (hash >> 12); |
| 510 srl(at, reg0, 12); | 509 srl(at, reg0, 12); |
| 511 xor_(reg0, reg0, at); | 510 xor_(reg0, reg0, at); |
| 512 | 511 |
| 513 // hash = hash + (hash << 2); | 512 // hash = hash + (hash << 2); |
| 514 sll(at, reg0, 2); | 513 Lsa(reg0, reg0, reg0, 2); |
| 515 addu(reg0, reg0, at); | |
| 516 | 514 |
| 517 // hash = hash ^ (hash >> 4); | 515 // hash = hash ^ (hash >> 4); |
| 518 srl(at, reg0, 4); | 516 srl(at, reg0, 4); |
| 519 xor_(reg0, reg0, at); | 517 xor_(reg0, reg0, at); |
| 520 | 518 |
| 521 // hash = hash * 2057; | 519 // hash = hash * 2057; |
| 522 sll(scratch, reg0, 11); | 520 sll(scratch, reg0, 11); |
| 523 sll(at, reg0, 3); | 521 Lsa(reg0, reg0, reg0, 3); |
| 524 addu(reg0, reg0, at); | |
| 525 addu(reg0, reg0, scratch); | 522 addu(reg0, reg0, scratch); |
| 526 | 523 |
| 527 // hash = hash ^ (hash >> 16); | 524 // hash = hash ^ (hash >> 16); |
| 528 srl(at, reg0, 16); | 525 srl(at, reg0, 16); |
| 529 xor_(reg0, reg0, at); | 526 xor_(reg0, reg0, at); |
| 530 And(reg0, reg0, Operand(0x3fffffff)); | 527 And(reg0, reg0, Operand(0x3fffffff)); |
| 531 } | 528 } |
| 532 | 529 |
| 533 | 530 |
| 534 void MacroAssembler::LoadFromNumberDictionary(Label* miss, | 531 void MacroAssembler::LoadFromNumberDictionary(Label* miss, |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 // Use reg2 for index calculations and keep the hash intact in reg0. | 571 // Use reg2 for index calculations and keep the hash intact in reg0. |
| 575 mov(reg2, reg0); | 572 mov(reg2, reg0); |
| 576 // Compute the masked index: (hash + i + i * i) & mask. | 573 // Compute the masked index: (hash + i + i * i) & mask. |
| 577 if (i > 0) { | 574 if (i > 0) { |
| 578 Daddu(reg2, reg2, Operand(SeededNumberDictionary::GetProbeOffset(i))); | 575 Daddu(reg2, reg2, Operand(SeededNumberDictionary::GetProbeOffset(i))); |
| 579 } | 576 } |
| 580 and_(reg2, reg2, reg1); | 577 and_(reg2, reg2, reg1); |
| 581 | 578 |
| 582 // Scale the index by multiplying by the element size. | 579 // Scale the index by multiplying by the element size. |
| 583 DCHECK(SeededNumberDictionary::kEntrySize == 3); | 580 DCHECK(SeededNumberDictionary::kEntrySize == 3); |
| 584 dsll(at, reg2, 1); // 2x. | 581 Dlsa(reg2, reg2, reg2, 1); // reg2 = reg2 * 3. |
| 585 daddu(reg2, reg2, at); // reg2 = reg2 * 3. | |
| 586 | 582 |
| 587 // Check if the key is identical to the name. | 583 // Check if the key is identical to the name. |
| 588 dsll(at, reg2, kPointerSizeLog2); | 584 Dlsa(reg2, elements, reg2, kPointerSizeLog2); |
| 589 daddu(reg2, elements, at); | |
| 590 | 585 |
| 591 ld(at, FieldMemOperand(reg2, SeededNumberDictionary::kElementsStartOffset)); | 586 ld(at, FieldMemOperand(reg2, SeededNumberDictionary::kElementsStartOffset)); |
| 592 if (i != kNumberDictionaryProbes - 1) { | 587 if (i != kNumberDictionaryProbes - 1) { |
| 593 Branch(&done, eq, key, Operand(at)); | 588 Branch(&done, eq, key, Operand(at)); |
| 594 } else { | 589 } else { |
| 595 Branch(miss, ne, key, Operand(at)); | 590 Branch(miss, ne, key, Operand(at)); |
| 596 } | 591 } |
| 597 } | 592 } |
| 598 | 593 |
| 599 bind(&done); | 594 bind(&done); |
| (...skipping 3232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3832 | 3827 |
| 3833 if (emit_debug_code()) { | 3828 if (emit_debug_code()) { |
| 3834 And(at, result, Operand(kDoubleAlignmentMask)); | 3829 And(at, result, Operand(kDoubleAlignmentMask)); |
| 3835 Check(eq, kAllocationIsNotDoubleAligned, at, Operand(zero_reg)); | 3830 Check(eq, kAllocationIsNotDoubleAligned, at, Operand(zero_reg)); |
| 3836 } | 3831 } |
| 3837 | 3832 |
| 3838 // Calculate new top and bail out if new space is exhausted. Use result | 3833 // Calculate new top and bail out if new space is exhausted. Use result |
| 3839 // to calculate the new top. Object size may be in words so a shift is | 3834 // to calculate the new top. Object size may be in words so a shift is |
| 3840 // required to get the number of bytes. | 3835 // required to get the number of bytes. |
| 3841 if ((flags & SIZE_IN_WORDS) != 0) { | 3836 if ((flags & SIZE_IN_WORDS) != 0) { |
| 3842 dsll(result_end, object_size, kPointerSizeLog2); | 3837 Dlsa(result_end, result, object_size, kPointerSizeLog2); |
| 3843 Daddu(result_end, result, result_end); | |
| 3844 } else { | 3838 } else { |
| 3845 Daddu(result_end, result, Operand(object_size)); | 3839 Daddu(result_end, result, Operand(object_size)); |
| 3846 } | 3840 } |
| 3847 Branch(gc_required, Ugreater, result_end, Operand(alloc_limit)); | 3841 Branch(gc_required, Ugreater, result_end, Operand(alloc_limit)); |
| 3848 | 3842 |
| 3849 // Update allocation top. result temporarily holds the new top. | 3843 // Update allocation top. result temporarily holds the new top. |
| 3850 if (emit_debug_code()) { | 3844 if (emit_debug_code()) { |
| 3851 And(at, result_end, Operand(kObjectAlignmentMask)); | 3845 And(at, result_end, Operand(kObjectAlignmentMask)); |
| 3852 Check(eq, kUnalignedAllocationInNewSpace, at, Operand(zero_reg)); | 3846 Check(eq, kUnalignedAllocationInNewSpace, at, Operand(zero_reg)); |
| 3853 } | 3847 } |
| (...skipping 1735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5589 | 5583 |
| 5590 // Pop the arguments, restore registers, and return. | 5584 // Pop the arguments, restore registers, and return. |
| 5591 mov(sp, fp); // Respect ABI stack constraint. | 5585 mov(sp, fp); // Respect ABI stack constraint. |
| 5592 ld(fp, MemOperand(sp, ExitFrameConstants::kCallerFPOffset)); | 5586 ld(fp, MemOperand(sp, ExitFrameConstants::kCallerFPOffset)); |
| 5593 ld(ra, MemOperand(sp, ExitFrameConstants::kCallerPCOffset)); | 5587 ld(ra, MemOperand(sp, ExitFrameConstants::kCallerPCOffset)); |
| 5594 | 5588 |
| 5595 if (argument_count.is_valid()) { | 5589 if (argument_count.is_valid()) { |
| 5596 if (argument_count_is_length) { | 5590 if (argument_count_is_length) { |
| 5597 daddu(sp, sp, argument_count); | 5591 daddu(sp, sp, argument_count); |
| 5598 } else { | 5592 } else { |
| 5599 dsll(t8, argument_count, kPointerSizeLog2); | 5593 Dlsa(sp, sp, argument_count, kPointerSizeLog2, t8); |
| 5600 daddu(sp, sp, t8); | |
| 5601 } | 5594 } |
| 5602 } | 5595 } |
| 5603 | 5596 |
| 5604 if (do_return) { | 5597 if (do_return) { |
| 5605 Ret(USE_DELAY_SLOT); | 5598 Ret(USE_DELAY_SLOT); |
| 5606 // If returning, the instruction in the delay slot will be the addiu below. | 5599 // If returning, the instruction in the delay slot will be the addiu below. |
| 5607 } | 5600 } |
| 5608 daddiu(sp, sp, 2 * kPointerSize); | 5601 daddiu(sp, sp, 2 * kPointerSize); |
| 5609 } | 5602 } |
| 5610 | 5603 |
| (...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6178 Register mask_reg) { | 6171 Register mask_reg) { |
| 6179 DCHECK(!AreAliased(addr_reg, bitmap_reg, mask_reg, no_reg)); | 6172 DCHECK(!AreAliased(addr_reg, bitmap_reg, mask_reg, no_reg)); |
| 6180 // addr_reg is divided into fields: | 6173 // addr_reg is divided into fields: |
| 6181 // |63 page base 20|19 high 8|7 shift 3|2 0| | 6174 // |63 page base 20|19 high 8|7 shift 3|2 0| |
| 6182 // 'high' gives the index of the cell holding color bits for the object. | 6175 // 'high' gives the index of the cell holding color bits for the object. |
| 6183 // 'shift' gives the offset in the cell for this object's color. | 6176 // 'shift' gives the offset in the cell for this object's color. |
| 6184 And(bitmap_reg, addr_reg, Operand(~Page::kPageAlignmentMask)); | 6177 And(bitmap_reg, addr_reg, Operand(~Page::kPageAlignmentMask)); |
| 6185 Ext(mask_reg, addr_reg, kPointerSizeLog2, Bitmap::kBitsPerCellLog2); | 6178 Ext(mask_reg, addr_reg, kPointerSizeLog2, Bitmap::kBitsPerCellLog2); |
| 6186 const int kLowBits = kPointerSizeLog2 + Bitmap::kBitsPerCellLog2; | 6179 const int kLowBits = kPointerSizeLog2 + Bitmap::kBitsPerCellLog2; |
| 6187 Ext(t8, addr_reg, kLowBits, kPageSizeBits - kLowBits); | 6180 Ext(t8, addr_reg, kLowBits, kPageSizeBits - kLowBits); |
| 6188 dsll(t8, t8, Bitmap::kBytesPerCellLog2); | 6181 Dlsa(bitmap_reg, bitmap_reg, t8, Bitmap::kBytesPerCellLog2); |
| 6189 Daddu(bitmap_reg, bitmap_reg, t8); | |
| 6190 li(t8, Operand(1)); | 6182 li(t8, Operand(1)); |
| 6191 dsllv(mask_reg, t8, mask_reg); | 6183 dsllv(mask_reg, t8, mask_reg); |
| 6192 } | 6184 } |
| 6193 | 6185 |
| 6194 | 6186 |
| 6195 void MacroAssembler::JumpIfWhite(Register value, Register bitmap_scratch, | 6187 void MacroAssembler::JumpIfWhite(Register value, Register bitmap_scratch, |
| 6196 Register mask_scratch, Register load_scratch, | 6188 Register mask_scratch, Register load_scratch, |
| 6197 Label* value_is_white) { | 6189 Label* value_is_white) { |
| 6198 DCHECK(!AreAliased(value, bitmap_scratch, mask_scratch, t8)); | 6190 DCHECK(!AreAliased(value, bitmap_scratch, mask_scratch, t8)); |
| 6199 GetMarkBits(value, bitmap_scratch, mask_scratch); | 6191 GetMarkBits(value, bitmap_scratch, mask_scratch); |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6505 if (mag.shift > 0) sra(result, result, mag.shift); | 6497 if (mag.shift > 0) sra(result, result, mag.shift); |
| 6506 srl(at, dividend, 31); | 6498 srl(at, dividend, 31); |
| 6507 Addu(result, result, Operand(at)); | 6499 Addu(result, result, Operand(at)); |
| 6508 } | 6500 } |
| 6509 | 6501 |
| 6510 | 6502 |
| 6511 } // namespace internal | 6503 } // namespace internal |
| 6512 } // namespace v8 | 6504 } // namespace v8 |
| 6513 | 6505 |
| 6514 #endif // V8_TARGET_ARCH_MIPS64 | 6506 #endif // V8_TARGET_ARCH_MIPS64 |
| OLD | NEW |